有没有办法将简单的 LINQ 查询封装在可与 LINQ to Entities 查询一起使用的扩展方法中?

Posted

技术标签:

【中文标题】有没有办法将简单的 LINQ 查询封装在可与 LINQ to Entities 查询一起使用的扩展方法中?【英文标题】:Is there any way to encapsulate a simple LINQ query in an extension method that can be used with LINQ to Entities query? 【发布时间】:2013-11-26 08:02:52 【问题描述】:

我知道类似的问题已经被问过很多次,但他们通常要求 LINQ to Entities 支持它不支持的功能,或者提供的解决方案不是我想要的。

我有一个简单的查询,我想将它封装在一个扩展方法中,以便它可以在任何地方使用:

public static Episode Latest(this ICollection<Episode> EpisodesSet)

    return EpisodesSet.OrderByDescending(e => e.AiredDate).FirstOrDefault();

这会产生带有错误的 NotSupportedException:

LINQ to Entities 无法识别方法 '[namespace/type/method here]' 方法,并且此方法无法转换为存储表达式

所以,“简单查询”是指OrderByDescending(expression).FirstOrDefault() 受 LINQ to Entities 支持/可翻译。另外,我知道我可以编写一个返回表达式的函数并执行类似episode = Episodes.Where(Latest()) 的操作,但这似乎不是很“可发现”,也不是我正在寻找的解决方案。

我想知道是否有办法重写我的扩展方法,以便当我尝试使用这样的扩展方法时 LINQ to Entities 不会抛出 NotSupportedException:

var query = from show in context.Shows      
            select new show.Title, show.Epsiodes.Latest();

【问题讨论】:

您的选择是在您的数据库上创建一些相应的过程(做同样的事情)或尝试构建您自己的表达式树。 您可以使用 LinqKit 做到这一点。你应该检查一下! 最新返回Episodewhere 需要一个布尔值。 @Servy,我想我的意思是 episode = Episodes.FirstOrDefault(EpisodesDescending) @threadster 我对此表示怀疑,因为该代码可以工作。他想从查询提供程序使用的表达式中调用该方法,这就是它不起作用的原因。 【参考方案1】:

你想要的是一些计算属性:

show.Epsiodes.Latest()

基本上,您希望在 Linq to Entities 查询中运行代码。那是不可能的。 Linq to Entities 永远无法理解 Latest() 的含义。

正如您所说,您可以做的是提供一个表达式并(可能)使用 LinqKit 以便在您需要的任何地方重用它。

有几个选项可以通过 Linq to Entities 使用计算属性。看我的回答here。

您可能想要的是第二个选项。这样您就可以执行以下操作:

var query = from show in context.Shows      
            select new show.Title, show.LatestEpsiode;

前提是您在Show 类中定义了一个计算属性,就像here 描述的那样。

【讨论】:

以上是关于有没有办法将简单的 LINQ 查询封装在可与 LINQ to Entities 查询一起使用的扩展方法中?的主要内容,如果未能解决你的问题,请参考以下文章

(转)Linq-DataSet

我应该使用 Linq 和 IQueryable<T> 来实现查询对象模式

有没有啥简单的方法可以在 Linq 中实现 SQL Server 的合并查询?

Linq to SQL中如何拦截和修改SQL查询

Linq语句

语言集成查询 (LINQ)