Andy Johnston
Andy Johnston

Reputation: 487

Linq to Entities - "Unable to create a constant value of type 'System.Object'..."

Can anyone tell me why this works in LinqPad but not as a C# expression in my app?

I am using Entity Framework...

from p in Productions
join t in MaterialTransactions
    on p.Prodn_ID equals t.Prodn_ID
where p.WO_ID == 2345
orderby p.Date descending
select new 
{
    Id = p.Prodn_ID,
    Date = p.Date,
    Line = (p.ProdLine.Factory.Factory_No + '/' + p.ProdLine.ProdLine_No.ToString()),
    Qty = p.Qty,
    Wgt = (double)p.ActWgt,
    Speed = (double)p.ActSpeed,
    MaterialUsed = t.Material.Name}

I am getting a System.Exception"Unable to create a constant value of type 'System.Object'. Only primitive types or enumeration types are supported in this context."

Upvotes: 0

Views: 5416

Answers (3)

Roger Johansson
Roger Johansson

Reputation: 23214

Duplicate question of what I had a few days ago: Best way to concat strings and numbers in SQL server using Entity Framework 5?

I created an ExpressionVisitor to solve the problem so I can write clean code and run as much as possible in a single query. (included in answer)

Upvotes: 1

Raphaël Althaus
Raphaël Althaus

Reputation: 60503

if you want to convert numeric values to string in linq to entities, you've got to use SqlFunctions (ToString() will fail)

(p.ProdLine.Factory.Factory_No + '/' + p.ProdLine.ProdLine_No.ToString())

should be

SqlFunctions.StringConvert((double)p.ProdLine.Factory.Factory_No) + '/' + SqlFunctions.StringConvert((double)p.ProdLine.ProdLine_No);

you've got to cast your numeric value to a double (or a decimal), as there's no overload for StringConvert taking an int as parameter.

Upvotes: 0

Maarten
Maarten

Reputation: 22955

I think it is the following line that causes the problems:

Line = (p.ProdLine.Factory.Factory_No + '/' + p.ProdLine.ProdLine_No.ToString())

This is since it combines a query-result with a .NET method result.

Maybe this will work. It delays the creation the of Line-variable-contents until after the query has been run.

var query = (from p in Productions
join t in MaterialTransactions
    on p.Prodn_ID equals t.Prodn_ID
where p.WO_ID == 2345
orderby p.Date descending
select new  {
    Id = p.Prodn_ID,
    Date = p.Date,
    Line1 = p.ProdLine.Factory.Factory_No,
    Line2 = p.ProdLine.ProdLine_No,
    Qty = p.Qty,
    Wgt = (double)p.ActWgt,
    Speed = (double)p.ActSpeed,
    MaterialUsed = t.Material.Name
})
.AsEnumerable()
// This is where the db-stuff stops, and the in-memory stuff begins
.Select(p => new {
    p.Id,
    p.Date,
    Line = p.Line1 + '/' + p.Line2.ToString(),
    p.Qty,
    p.Wgt,
    p.Speed,
    p.MaterialUsed
});

var result = query.ToList();

Upvotes: 0

Related Questions