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

发布于 2024-11-01 03:04:51 字数 1645 浏览 5 评论 0原文

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

指定的类型成员“Title”是 LINQ to Entities 不支持。 仅初始值设定项、实体成员和 实体导航属性是 支持。

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

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

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

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()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南街女流氓 2024-11-08 03:04:51

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文