Can I create a LINQ-to-Entity query on non-Entity Member fields
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-usi开发者_运维知识库ng-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()
?
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.
精彩评论