Reputation: 564
I have the enumeration:
public enum CmdType {
[Display(Name = "abc")]
AbcEnumIdentifier = 0,
[Display(Name = "xyz")]
XyzEnumIdentifier = 1,
...
}
I'd like to get the names of each enumeration into my query, but even using .WithTranslations()
I'm getting this error:
LINQ to Entities does not recognize the method 'System.String GetName(System.Type, System.Object)' method, and this method cannot be translated into a store expression.
The query:
var joinedRecord =
(
from m in mTable
join b in bTable on m.Id equals b.aRefId
select new {
aId = a.Id,
aAttrib1 = a.Attrib1
...
bCmdType = Enum.GetName(typeof(CmdType), b.CmdType)
}
).WithTranslations();
How do I return a generated value using Enum.GetName(...)
within the query?
Upvotes: 7
Views: 6655
Reputation: 5489
LINQ to entities tries to translate your query to SQL and it fails to do so, because there is no equivalent of the Enum.GetName
method in SQL.
You need to materialize the results of the query and convert the enum values to their name in the memory.
var joinedRecords = (
from m in mTable
join b in bTable on m.Id equals b.aRefId
select new {
aId = a.Id,
aAttrib1 = a.Attrib1
...
bCmdType = b.CmdType
}
).AsEnumerable() //Executes the query, further you have simple CLR objects
.Select(o => new {
aId = o.Id,
aAttrib1 = o.Attrib1
...
bCmdTypeName = Enum.GetName(typeof(CmdType), o.CmdType)
});
Upvotes: 6
Reputation: 4113
You are calling Enum.GetName(typeof(CmdType), b.CmdType)
which cannot be translated to SQL as the Enum
definition is not in the DB if you take a look at your rows you'll see there is an int
instead of the name of the Enum
value in question.
Try this:
var joinedRecord =
(
from m in mTable
join b in bTable on m.Id equals b.aRefId
select new {
aId = a.Id,
aAttrib1 = a.Attrib1
...
bCmdType = b.CmdType
}
)
.AsEnumerable() // or ToList()
.Select( // map to another type calling Enum.GetName(typeof(CmdType), b.CmdType) )
.WithTranslations();
What this does is that by calling AsEnumerable()
or ToList()
you are no longer processing an instance of IQueryable<T>
(which is what your original query returns, on the bad side once you do this all returned objects will be on memory). So once you have objects in memory you can use them just as any other C# object which should allow you to use the methods you want.
Upvotes: 5
Reputation: 12304
Try casting to AsEnumerable() so you can use LINQ to Objects. LINQ to Entities will try to translate it to SQL for which there is no equivalent:
var joinedRecord =
(from m in mTable
join b in bTable on m.Id equals b.aRefId)
.AsEnumerable()
.Select(x => new {
aId = a.Id,
aAttrib1 = a.Attrib1
...
bCmdType = Enum.GetName(typeof(CmdType), b.CmdType)
})
.WithTranslations();
See http://www.lavinski.me/ef-linq-as-emumerable/
Upvotes: 2