实体框架查询中的自定义功能有时会正确翻译,有时则不会

时间:2010-08-02 23:08:25

标签: c# sql linq entity-framework

我有这个功能:

public static IQueryable<Article> WhereArticleIsLive(this IQueryable<Article> q)
{
    return q.Where(x =>
        x != null
        && DateTime.UtcNow >= x.PublishTime
        && x.IsPublished
        && !x.IsDeleted);
}

它在这个查询中运行得很好:

from a in Articles.WhereArticleIsLive()
where a.Id == 5
select new { a.Title }

但它在这个稍微复杂一点的查询中不起作用:

from s in Series
from a in Articles.WhereArticleIsLive()
where s.Id == a.SeriesId
select new { s, a }

我收到此错误消息:

  

NotSupportedException:LINQ to Entities无法识别方法'System.Linq.IQueryable 1[TheFraser.Data.Articles.Article] WhereArticleIsLive(System.Linq.IQueryable 1 [TheFraser.Data.Articles.Article])'方法,并且此方法无法转换为商店表达式。< / p>

知道为什么吗?有没有其他方法来整合这样的查询参数?

提前致谢。

1 个答案:

答案 0 :(得分:3)

编辑:克雷格的更正。

我要离开这里了,因为我觉得这是一个很有价值的工具:使用linqkit!但不是为了解决这个问题: - )

不使用返回IQueryable,而是使用Expression来分解谓词。例如。您可以在Article:

上定义以下静态方法
public static Expression<Func<Article,bool>> IsLive()
{
    return x =>
    x != null
    && DateTime.UtcNow >= x.PublishTime
    && x.IsPublished
    && !x.IsDeleted
}

然后,确保在构建查询时存储对此表达式的引用,这与(未测试)一致:

var isLive = Article.IsLive();

from s in Series
from a in Articles.Where(isLive)
where s.Id == a.SeriesId
select new { s, a }