我可以在非实体成员字段上创建linq到实体查询吗?



我有一个使用partial class语法扩展的实体类,以具有一些派生属性。我想使用IQueryable<T>接口执行查询,该接口使用来自这些字段的信息,但我目前得到一个异常,状态为

指定的类型成员'Title'是不支持LINQ到实体。只有初始化式、实体成员和实体导航属性是支持。

下面是相关的代码片段。你可以假设实体对象有一个名为Id的String成员。

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();
}

作为最后的手段,我总是可以在SkipTake之前做AsEnumerable(),但这将涉及从数据库中检索所有对象,即使选择可以由SQL完成。

也许最好的选择是使用反射来检查对象属性是否有DataMemberAttribute,然后选择query.OrderBy().Skip().Take().AsEnumerable()query.AsEnumerable().OrderBy().Skip().Take() ?

不,你不能,因为链接到实体查询只是表达式树转换为SQL。为了将树转换为SQL,使用实体映射,因为Title不在映射中,它将抛出异常。

SkipTake之前调用AsEnumerable听起来是非常糟糕的设计,因为它总是将整个数据表的内容传输到应用程序。这将是非常缓慢的,在大数据表的情况下也是无用的。

如果这是本地化问题,您的数据库必须包含本地化字符串才能使其有效。同时,如果您只需要对少数记录执行此操作,则可以加载所有记录

相关内容

  • 没有找到相关文章

最新更新