2

我有一个名为批处理的实体框架对象,该对象与项目具有一对多的关系。

所以 1 批有很多项目。每个项目都有很多问题。

我想过滤具有特定问题代码(x.code == issueNo)的批处理项目。我写了以下内容,但出现此错误:

        items = batch.Select(b => b.Items
                     .Where(i => i.ItemOrganisations
                     .Select(o => o
                     .Issues.Select(x => x.Code == issueNo)))); 

错误一:

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   
4

5 回答 5

3

Select扩展方法需要一个返回布尔值的 lambda 表达式,但内部o.Issues.Select返回布尔值的 IEnumerable 到外部Select(o => o,这会导致您得到异常。

尝试使用Any来验证至少一个元素验证条件:

    items = batch.Select(
               b => b.Items.Where(
                             i => i.ItemOrganisations.Any(
                                     o => o.Issues.Any(x => x.Code == issueNo)
                                  )
                    )
            ); 
于 2013-07-20T23:43:11.697 回答
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如果您需要避免重复项,您始终可以将其包装在 a中:

var items = (from item in batch.Items
            from org in item.ItemOrganizations
            from issue in org.Issues
            where issue.Code == issueNo
            select item).Distinct();
于 2013-07-20T23:45:51.277 回答
0

很难根据您的代码来判断您要做什么,但我认为您正在寻找这样的东西;

var issue = batch.Select(b => b.Items).Select(i => i.Issues).Where(x => x.Code == issueNo).Select(x => x).FirstOrDefault();

上述查询将返回 Issues Code 属性等于 issueNo 的第一个问题。如果不存在此类问题,它将返回 null。

查询中的一个问题(第一个错误的原因)是您使用 select 就像它是查询末尾的 where 子句。Select 用于投影一个参数,当你做Select(x => x.Code == issueNo)你正在做的事情是将 x.Code 投影到一个 bool 时,该 select 返回的值是 的结果x.Code == issueNo,看起来你想要那个条件在 where 子句中然后你想要返回满足它的问题,这就是我的查询正在做的事情。

于 2013-07-20T23:46:00.990 回答
0
items =  from b in batch.Include("Items")
         where b.Items.Any(x=>x.Code==issueNo)
         select b;
于 2013-07-20T23:46:34.423 回答
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 提供正确答案),但我认为它更容易阅读。

于 2013-07-21T00:17:54.657 回答