在Enitity Framework中我想在另一个linq查询的where子句中使用linq查询。
public class A {
}
public class B {
public A A { get; set; }
}
public class AB {
public A A { get; set; }
public B B { get; set; }
}
IEnumerable<MassiveObject> filteredData = ... // MassiveObject contains A and some more attributes
var query = from b in db.Bs
.Include("A")
where filteredData.Where(x => x.A.equals(b.A)).Count() > 0 // filteredAs contains an object that contains the same A as the b's A
select new AB {
A = filteredData.Where(a => a.equals(b.A)),
B = b
};
看起来LINQ不支持这一点。 “无法创建类型为'MassiveObject'的常量值。在此上下文中仅支持基本类型或枚举类型。”无论是第一次使用还是第二次使用嵌套的linq。
在执行查询后,如果没有循环查询结果,还有另一种方法吗?
答案 0 :(得分:3)
Linq不支持在SQL构造中使用对象的枚举,因为没有办法让SQL stement开始。
拉出b,然后在该枚举中过滤。
答案 1 :(得分:3)
filteredData
是一个存在于进程内存中的集合。另一方面,EF查询被转换为在SQL服务器上运行的SQL。
SQL服务器无法知道进程内存中存在哪些数据,即使它可以看到内存SQL仍然没有对象实例或迭代的概念。所以你要做的事情根本不可能。
答案 2 :(得分:1)
你不能像这样混合内存和SQL LINQ查询。相反,您需要在进行连接之前将SQL数据拉入内存。
尝试这样的事情:
var query =
from b in db.Bs.Include("A").ToArray()
join a in filteredData.Select(x => x.A) on b.A equals a into gas
where gas.Any() // or use gas.Count() > 0
select new AB
{
A = gas.First(),
B = b,
};
请注意将SQL数据带入内存的.ToArray()
调用。
答案 3 :(得分:0)
目前还不是很清楚你想要实现的目标,但是,以前的查询可以通过各种方式在当前查询中使用,例如。
query2 = source.Where(s => query1.Contains(s));
或使用LINQ连接。
在你的情况下,它看起来像你试图重用过滤器,而不是查询。
您可以使用从IQueryable<T>
到IQueryable<T>
的扩展方法或使用表达式来实现此目的。
e.g。
static class MyExtensions
{
public static void IQueryable<T> FilterResults(this IQueryable<T> query)
{
return query.Where(i => i....);
}
}
然后像这样使用:
query2 = query.FilterResults().Where(...);
有关使用表达式树的替代方法的详细信息,请参阅此MSDN article。