Is it possible to develop a LINQ-to-Entity query that includes non-Entity Member fields?

dynamic-linq entity-framework-4 iqueryable linq-to-entities reflection

Question

I have an Entity class that I have extended using the partial class syntax to have some derived properties. I would like to perform a query using the IQueryable<T> interface that uses the information from these fields, but I currently get an exception that states

The specified type member 'Title' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Here are the relevant code snippets. You may assume that the Entity object has a String member named Id.

public partial class MyEntityObject
{
   public String Title { get { return MyStrings.ResourceManager.GetString(Id) ?? ""; } }
}

/**
 * Throws exception trying to sort on the 'Title' field of a 'MyEntityObject'
 */
public IEnumerable<T> Query<T>(String fieldName, int low, int high)
{
   // Get the ObjectContext<T> using a Repository pattern
   var query = context.GetRepository<T>()

   // Create an OrderBy clause based on the field by dynamically building an expression tree
   //  see http://stackoverflow.com/questions/4546463/help-with-linq-and-generics-using-getvalue-inside-a-query
   PropertyInfo propertyInfo = typeof(T).GetProperty(fieldName);

   ParameterExpression e = Expression.Parameter(typeof(T), "e");
   MemberExpression mexpr = Expression.MakeMemberAccess(e, propertyInfo);

   IQueryable<T> sortedQuery = query.OrderBy(Expression.Lambda<Func<T,Object>>(mexpr, e));
   return sortedQuery.Skip(low).Take(high - low + 1).AsEnumerable();
}

As a last resort I can always do the AsEnumerable() before the Skip and Take, but that will involve retrieving all of the objects from the database even if the selection can be done by SQL.

Perhaps the best alternative is to use reflection to check that the object property has a DataMemberAttribute and then chose to do either query.OrderBy().Skip().Take().AsEnumerable() or query.AsEnumerable().OrderBy().Skip().Take()?

1
1
4/13/2011 7:26:51 PM

Accepted Answer

No you can't because linq-to-entities query is just expression tree translated to SQL. To translate the tree to SQL your entity mapping is used and because Title is not in your mapping it will throw exception.

Calling AsEnumerable before Skip and Take sounds like very bad design because it will always transfer content of whole data table to your application. This will be very slow and in case of big data tables also useless.

If this is a problem of localization your database must contain localized strings to make this effective. In the same time if you need to do this only with few records you can load all of them.

3
4/13/2011 7:32:41 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow