1

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

LINQ to Entities 不支持指定的类型成员“标题”。仅支持初始化程序、实体成员和实体导航属性。

以下是相关的代码片段。您可以假设 Entity 对象有一个名为 的 String 成员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();
}

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

也许最好的替代方法是使用反射来检查对象属性是否具有 aDataMemberAttribute然后选择执行query.OrderBy().Skip().Take().AsEnumerable()or query.AsEnumerable().OrderBy().Skip().Take()

4

1 回答 1

3

不,您不能,因为 linq-to-entities 查询只是转换为 SQL 的表达式树。要将树转换为 SQL,使用您的实体映射,因为Title不在您的映射中,它会抛出异常。

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

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

于 2011-04-13T19:32:41.733 回答