使用在LINQ中将IQueryable返回到实体的自定义方法

时间:2016-06-21 12:54:05

标签: c# entity-framework linq linq-to-entities

我有两种返回IQueryable的方法:

IQueryable<Person> GetGoodPeople();

IQueryable<Person> GetBadPeople(); 

我需要写这个查询:

var q = from x in GetGoodPeople()
        from y in GetBadPeople()
        select new { Good = x, Bad = y };

linq to实体不支持上面的代码(抛出NotSupportedException),除了我声明一个变量并在查询中使用它:

var bad = GetBadPeople()
var q = from x in GetGoodPeople()
        from y in bad
        select new { Good = x, Bad = y };

有没有办法可以直接在linq中使用IQueryable方法?

2 个答案:

答案 0 :(得分:3)

简短回答 - 这不可能可行。您的修复是解决问题的正确方法。

一旦实体框架(以及LINQ2Sql)开始解析表达式树,就太晚了。对GetBadPeople()的调用实际上是懒惰地执行,因此,尝试将其转换为SQL 本身

这是它的样子:

Table(Person).Take(1).SelectMany(x => value(UserQuery).GetBadPeople(), (x, y) => new <>f__AnonymousType0`2(Good = x, Bad = y))

在这里,我写了GetGoodPeople()只是简单地返回People.Take(1)。请注意该查询是如何 verbatim ,但GetBadPeople()包含函数调用。

在表达式之外评估GetBadPeople()的解决方法是正确的解决方案。这会导致表达式树调用Expression.Constant(bad),而不是尝试调用GetBadPeople()

这使查询看起来像这样:

Table(Person).Take(1).SelectMany(x => value(UserQuery+<>c__DisplayClass1_0).bad, (x, y) => new <>f__AnonymousType0`2(Good = x, Bad = y))

注意这里没有方法调用 - 我们只是传入变量。

答案 1 :(得分:0)

您可以使用无约束连接来近似笛卡尔积。它似乎不容易受到NotSupportedException的影响。我检查了后端,它呈现了一个单独的sql语句。

var q = from x in GetGoodPeople()
        join y in GetBadPeople()
        on 1 equals 1
        select new { Good = x, Bad = y };