我有一个名为batch的实体框架对象,这个对象与项目有1对多的关系。
所以1批次有很多项目。每个项目都有很多问题。
我想过滤具有特定问题代码的批处理项目(x.code == issueNo)。 我写了以下但我得到了这个错误:
items = batch.Select(b => b.Items
.Where(i => i.ItemOrganisations
.Select(o => o
.Issues.Select(x => x.Code == issueNo))));
错误1:
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<bool>>' to 'bool'
错误2:
Cannot convert lambda expression to delegate type 'System.Func<Ebiquity.Reputation.Neptune.Model.Item,bool>' because some of the return types in the block are not implicitly convertible to the delegate return type
答案 0 :(得分:3)
Select
扩展方法需要一个返回布尔值的lambda表达式,但内部o.Issues.Select
会向外部Select(o => o
返回一个IEnumerable boolean,这会导致您获得异常。
尝试使用Any
来验证至少有一个元素验证条件:
items = batch.Select(
b => b.Items.Where(
i => i.ItemOrganisations.Any(
o => o.Issues.Any(x => x.Code == issueNo)
)
)
);
答案 1 :(得分:2)
如果我理解正确,你试图通过多层枚举来选择。在这些情况下,您需要SelectMany
来平整图层,而不是Select
。 LINQ的语法糖专门用于使SelectMany
更易于推理:
var items = from item in batch.Items
from org in item.ItemOrganizations
from issue in org.Issues
where issue.Code == issueNo
select item;
编译器将其转换为以下内容:
var items = batch.Items
.SelectMany(item => item.ItemOrganizations, (item, org) => new {item, org})
.SelectMany(@t => @t.org.Issues, (@t, issue) => new {@t, issue})
.Where(@t => @t.issue.Code == issueNo)
.Select(@t => @t.@t.item);
如果您需要避免重复项目,可以随时将其包装在Distinct
中:
var items = (from item in batch.Items
from org in item.ItemOrganizations
from issue in org.Issues
where issue.Code == issueNo
select item).Distinct();
答案 2 :(得分:0)
根据您的代码很难说出您要做的事情,但我认为您正在寻找类似的内容;
var issue = batch.Select(b => b.Items).Select(i => i.Issues).Where(x => x.Code == issueNo).Select(x => x).FirstOrDefault();
上述查询将返回第一个问题,其中“问题代码”属性等于issueNo。如果不存在此类问题,则返回null。
您的查询中的一个问题(第一个错误的原因)是您正在使用select,就像它是查询末尾的where子句一样。选择用于投射参数,当你执行Select(x => x.Code == issueNo)
你正在做的是将x.Code投射到bool时,该选择返回的值是x.Code == issueNo
的结果,看起来像你想要在where子句中使用该条件,然后你想返回满足它的问题,这就是我的查询正在做的事情。
答案 3 :(得分:0)
items = from b in batch.Include("Items")
where b.Items.Any(x=>x.Code==issueNo)
select b;
答案 4 :(得分:0)
你迷失在lambdas中。你的LINQ链都是相互嵌入的,这使得它更难以推理。我在这里推荐一些辅助函数:
static bool HasIssueWithCode(this ItemOrganization org, int issueNo)
{
return org.Issues.Any(issue => issue.Code == issueNo);
}
static bool HasIssueWithCode(this Item items, int issueNo)
{
return items.ItemOrganizations.Any(org => org.HasIssueWithCode(issueNo));
}
然后你的回答很简单,很明显
var items = batch.Items.Where(item => item.HasIssueWithCode(issueNo));
如果你内联这些函数,结果与manji完全相同(所以给出正确答案的manji信用),但我认为它更容易阅读。