2010-02-11 82 views
16

我有一个类Post这是一个Entity Framework模型。它包含了这样的特性:如何在LINQ-to-Entities查询中使用自定义属性?

public bool Showable { 
    get { 
    return this.Public && this.PublishedDate > DateTime.now 
    } 
} 

我可以用它在这样的查询:

from p in db.Posts where p.Showable select p; 

,但是当我有一个使用它的属性,这样

public IEnumerable<Post> ShowablePosts { 
    get { 
    return from p in db.Posts where p.Showable select p; 
    } 
} 

那么我做不到:

from p in ShowablePosts where p.Id > 42 select p; 

它s ays:

LINQ to Entities不支持指定的类型成员'Showable'。仅支持初始化程序,实体成员和实体导航属性。

回答

1

不幸的是,实体框架根本不支持计算特性(也就是说,返回一个计算值,而不是一个参考支持字段属性),但it may be supported at a future date.

+0

我可以在查询中调用计算属性,但不能在运行查询的方法中调用。有点奇怪。 – Pablo 2010-02-11 01:41:33

+0

我现在生活在Linq-to-SQL的世界里,是从'db.Posts'中返回p。可显示select p;'本地是'IQueryable '还是'IEnuemerable '在EF中?这对他的问题有影响吗? – 2010-02-11 01:42:54

+0

@J。 Pablo Fernandez:当您定义Linq查询时,只有当您执行需要实际结果的事情时才执行。 Linq支持很多事情,但实体框架不支持,而这些事情只有在执行查询后才会变得明显。 – 2010-02-11 03:34:45

19

,如果你能做到这一点您将该属性编写为Expression,可翻译为SQL。

Here's how to do it.

这是一个有点复杂,因为它是一个复杂的问题的通用解决方案。

总的想法是这样的:LINQ to Entities(如所有 LINQ提供程序)无法在运行时将编译后的代码(如属性)转换为SQL。 LINQ to Objects可以执行编译的代码,但是它不能翻译它。但他们可以翻译Expression<T>。所以,你可以写:

public static Expression<Func<Post, bool>> WhereActive 
{ 
    get 
    { 
     return p => p.Public && p.PublishedDate > DateTime.Now; 
    } 
} 

然后,你可以写:

public IEnumerable<Post> ShowablePosts 
{ 
    get 
    { 
     return db.Posts.Where(WhereActive); 
    } 
} 

...和LINQ to实体可以翻译这一点。链接后的代码概括了这个想法。

+0

有没有办法将参数传递给WhereActive?例如DateTime。如果是这样,您可能能够回答https:// stackoverflow。com/q/48497487/2968001 – 2018-01-29 10:13:49

0

我认为最简单的方法是使用DelegateDecompiler.EntityFrameworkComputed属性,该属性在this answer中提到。

相关问题