Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何按子对象值属性筛选实体类型框架对象?_C#_Linq_Entity Framework - Fatal编程技术网

C# 如何按子对象值属性筛选实体类型框架对象?

C# 如何按子对象值属性筛选实体类型框架对象?,c#,linq,entity-framework,C#,Linq,Entity Framework,我有一个名为batch的实体框架对象,该对象与项有1对多关系 所以一批有很多项目。每一项都有很多问题 我想过滤具有特定问题代码(x.code==issueNo)的批处理项目。 我写了以下内容,但我收到了这个错误: items = batch.Select(b => b.Items .Where(i => i.ItemOrganisations .Select(o => o

我有一个名为batch的实体框架对象,该对象与项有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' 
无法将类型“System.Collections.Generic.IEnumerable”隐式转换为“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   
无法将lambda表达式转换为委托类型“System.Func”,因为块中的某些返回类型不能隐式转换为委托返回类型

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)
                                  )
                    )
            ); 

如果我理解正确,您正在尝试通过多层枚举进行选择。在这种情况下,您需要
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);
如果需要避免重复项目,您可以始终将其包装在一个不同的
中:

var items = (from item in batch.Items
            from org in item.ItemOrganizations
            from issue in org.Issues
            where issue.Code == issueNo
            select item).Distinct();

很难根据您的代码判断您正在尝试做什么,但我认为您正在寻找类似的东西

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投影到布尔,该选择返回的值是
x.code==issueNo
的结果,似乎您希望在where子句中包含该条件,然后您希望返回满足该条件的问题,这就是我的查询所做的。

您正在lambdas中迷失。您的LINQ链是all相互嵌入,更难推理。我推荐一些助手函数:

items =  from b in batch.Include("Items")
         where b.Items.Any(x=>x.Code==issueNo)
         select b;
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),但我认为这更容易阅读。

我现在没有编译器,但类似的东西可能会工作:items=batch.items.Select(x=>x.Issues.Any(I=>I.Code==issueNo));您可能不想这样排列您的语句。这意味着您一直在处理批处理。manji的答案有更多惯用的间距,但如果您发现自己做得这么多,可能最好制作一些帮助函数,如我的第二个答案。@xer说manji的答案会快一点,因为他的
Select
只返回一次项目。如果项目上存在多个问题,且相应的问题不存在,则我的项目将返回多次。因此,我的项目需要
Distinct
,而manji的项目不应该需要它。