views:

1425

answers:

3

Hi,

I have extended my entities to implement specific interfaces for its type. I am trying to perform the following query:

 var results = from x in context.MyEntityTable
               where x.AProperty == AValue
               select x;

 return results.Count() > 0 ? results.Cast<IApplicationEntity>().ToList() : null;

However, I keep getting the following error:

"LINQ to Entities only supports casting Entity Data Model primitive types"

Basically what I want to do is always convert the results from the raw entity type to a generic list of the interface it implements.

Is this possible?

+6  A: 

You can do the cast on the client, bypassing the entity framework query translation layer by calling AsEnumerable extension method:

return results.Count() > 0
       ? results.AsEnumerable().Cast<IApplicationEntity>().ToList() 
       : null;

However, it's better to reverse the order of doing the Count check:

var list = results.AsEnumerable().Cast<IApplicationEntity>().ToList();
return list.Count == 0 ? null : list;
Mehrdad Afshari
+1, however this will execute two DB queries (for Count and for ToList)... it would probably be better to call ToList before, then check the number of items
Thomas Levesque
@Thomas: Look at the second query.
Mehrdad Afshari
Yes, that's better ;)
Thomas Levesque
Thanks its amazing how simple things like the way you do a check the count improves efficiency!
James
A: 
return results.Count() > 0 ? 
results.Select(result => (IApplicationEntity)result)
.ToList() : null;
Spence
I don't think it will work, for the same reason the Cast method doesn't. You need to convert the query to an IEnumerable first
Thomas Levesque
The message states that it doesn't know how to transform the Cast() operator in linq to entities. This is actually code that is written by the provider of the linq provider (eg. Linq to Sql, linq to Objects etc.)Other posters have proposed to change the call to AsEnumerable to force the use of Linq to Objects and thus have the Cast() operator succeed. I was doing the same thing but using C# instead by explicitly projecting a cast into the code. Try it and let me know if it worked.
Spence
+2  A: 

If you want to cast your results to a complex type, you need to force the code to use LINQ to Objects rather than LINQ to Entities.

Calling the AsEnumerable extension method before the cast is the trick here.

Try the following:

var results = from x in context.MyEntityTable
              where x.AProperty == AValue
              select x;

return results.AsEnumerable().Cast<IApplicationEntity>().ToList();

Also note that it's not wise to check Count() on the enumerable, since it means the collection is iterated over twice.

Noldorin
Actually, this won't work. You should do the `AsEnumerable` *before* the cast. Otherwise, EF will try to translate it to a query to run on the provider.
Mehrdad Afshari
@Mehrdad: Too quick for your own good. I edited the post just before your comment. ;)
Noldorin