【发布时间】:2021-12-20 05:05:34
【问题描述】:
以下教科书 Join 查询运行良好:
var list = from family in db.Families.Where(f => !f.isDeleted)
join member in db.Members.Where(m => !m.isDeleted)
on family.Id equals member.FamilyID
select new { family = family.LastName, member = member.DisplayName };
list 是IQueryable: {Microsoft.FrameworkCore.Query.Internal.EntityQueryable<<>f__AnonymousType0<string, string>>},我可以打电话给list.ToList()。
但是,如果我在第一个 Where 中使用谓词,而不是使用 lambda,如下所示:
Predicate<Family> query = f => !f.isDeleted;
var list = from family in db.Families.Where(new Func<Family, bool>(query))
join member in db.Members.Where(m => !m.isDeleted)
on family.Id equals member.FamilyID
select new { family = family.LastName, member = member.DisplayName };
然后list 变为[IEnumerable]: {System.Linq.Enumerable.<JoinIterator>d__105<Family, Member, short, <>f__AnonymousType0<string, string>>},结果视图抛出“已经有一个打开的 DataReader 与此连接关联,必须先关闭。”。
我无法再重现它,但我确信有时结果视图会引发“数据为空”异常。
我需要使我的过滤器成为一个变量,因为所需的确切过滤器取决于其他一些条件。为什么使用Predicate 赋值会导致list 的类型不同,我该如何解决这个错误?
【问题讨论】:
-
您正在调用
Where的不同重载。你应该在那里传递Expression<Func<Family, bool>>,而不是Func<Family, bool>。 -
我该怎么做?我将
query更改为Expression<Predicate<Family>> query = f => !f.isDeleted;,但无法将其放入.Where(query)。 -
请再次阅读我的评论。我没说
Expression<Predicate<Family>>。 -
谢谢。现在可以了。我理解错了
Predicate<T>和Func<T, bool>一样。 -
它在概念上是相同的,但它们仍然是不同类型的委托,即使它们具有相同的签名。而 Where 则特别期望 Func。
标签: c# entity-framework predicate func