首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >然后使用条件记录加法选择GroupBy

然后使用条件记录加法选择GroupBy
EN

Stack Overflow用户
提问于 2022-07-07 12:04:43
回答 2查看 67关注 0票数 2

我有LINQ查询,在这个查询中,我必须使用一个结果集进行响应,这取决于内部字段集合。我已经通过LINQ查询完成了这件事,然后是一个foreach,但是我想要避免foreach循环,并通过

代码语言:javascript
运行
复制
List<ResultModel> result = new List<ResultModel>();           
var tempResultSet = _context.MainRecordTable.Where(h => h.id)
    .Select(lev => new 
    {
        Contacts = (lev.basetable2 != null 
                            && lev.basetable2.basetable3 != null 
                            && lev.basetable2.basetable3.basetable6 != null
                            &&  lev.basetable2.basetable3.basetable6.Any(h=>h.contact != null)
                            ? lev.basetable2.basetable3.basetable6.Where(h=>h.contact != null).Select(h=>h.contact).Distinct() : null),
        Key1 = lev.basetable5 != null ? lev.basetable5.Id : null,
        Key2 = lev.basetable2 != null && lev.basetable2.basetable3 != null && lev.basetable2.basetable3.basetable4 != null ?
                            lev.basetable2.basetable3.basetable4.id      : null

    })
    .Distinct()
    .ToList();

foreach (var x in tempResultSet)
{
    if (x.Contacts != null)
    {
        foreach (var contact in x.Contacts)
        {
            result.Add(new ResultModel
            {
                Key1 = x.Key1,
                Key2 = x.Key2,                           
                ContactKey = contact.id
            });
        }
    }
    else
    {
        result.Add(new ResultModel
        {
            Key1 = x.Key1,
            Key2 = x.Key2                        
        });
    }
}

return result;

我最后的Linq查询如下

返回_context.baseTable1.Where(h => h.id == Id ).Select(lev =>新的{ Contact = (lev.baseTable2 != null &lev.base Table2.base.Select 3 != null &lev.base Table2.base Table3.base Table5),任何(h => h.contact != null)吗?(h => h.contact != null).GroupBy(h => h.contact: null),Key1 = lev.office != null?lev.office.id,:null,Key2 = lev.baseTable2 != null &lev.base Table2.base 3 != null &lev.base Table2.base Table3 != null!=null?Lev.base Table2.base Table3.base Table4.id: null

代码语言:javascript
运行
复制
        }).ToList().SelectMany(x =>
        {
            if (!x.Contact.Any())
            {
                return new List<FinalModel> { new FinalModel { Key1 = x.Key1, Key2 = x.Key2 } };
            }
            else
                return x.Contact.Select(contact => new FinalModel()
                {
                    ContactKey = contact.id,
                    Key1 = x.Key1,
                    Key2 = x.Key2
                });
        });
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-07 12:20:44

您可以使用SelectMany来扁平数组,例如:

代码语言:javascript
运行
复制
List<ResultModel> result = _context.MainRecordTable.Where(h => h.id)
    .Select(lev => new 
    {
        Contacts = (lev.basetable2 != null 
                            && lev.basetable2.basetable3 != null 
                            && lev.basetable2.basetable3.basetable6 != null
                            &&  lev.basetable2.basetable3.basetable6.Any(h=>h.contact != null)
                            ? lev.basetable2.basetable3.basetable6.Where(h=>h.contact != null).Select(h=>h.contact).Distinct() : null),
        Key1 = lev.basetable5 != null ? lev.basetable5.Id : null,
        Key2 = lev.basetable2 != null && lev.basetable2.basetable3 != null && lev.basetable2.basetable3.basetable4 != null ?
                            lev.basetable2.basetable3.basetable4.id      : null

    })
    .Distinct()
    .ToList()
    .SelectMany(x => {
      if (x.Contacts == null)
        return new ResultModel[]  
        {
          Key1 = x.Key1, 
          Key2 = x.Key2,
        };
      else 
        return x.Contacts.Select(contact => new ResultModel() 
          { 
            Key1 = x.Key1, 
            Key2 = x.Key2, 
            ContactKey = contact.id,
          }).ToArray();        
    })
    .ToList();

SelectMany中,将检查是否设置了联系人列表;如果没有,则返回单个项目,否则将返回每个联系人的项目。

票数 2
EN

Stack Overflow用户

发布于 2022-07-07 15:37:02

我会发现,为没有联系人键的结果创建一个ResultModel子集合和用一个联系人键为结果创建另一个子集合更容易读。我怀疑随着时间的推移,这种方法也会比一个Linq表达式更容易维护。

您可以首先对临时结果进行分组,以便一个子集合包含临时结果而没有 contacts,而另一个子集合包含临时结果(E 210E 111联系人E 212)。

通过使用具有适当条件的包含联系人的.ToLookup(),很容易获得这种分组。

代码语言:javascript
运行
复制
var tempResultByContainingContacts = tempResultSet
    .ToLookup(x => x.Contacts != null && x.Contacts.Any());

(我添加了&& x.Contacts.Any()条件。如果这不适合您的用例,您可以忽略它。)

在定义了查找表之后,您有:

  • 临时结果无联系人tempResultByContainingContacts[false]中的
  • 临时结果与 contacts in tempResultByContainingContacts[true]

现在,可以根据临时结果计算一个结果子集合,而不需要 contacts。

代码语言:javascript
运行
复制
var resultWithoutContactKey = tempResultByContainingContacts[false]
    .Select(x => new ResultModel
    {
        Key1 = x.Key1,
        Key2 = x.Key2
    });

以及基于临时结果和 contacts生成的子集合。

代码语言:javascript
运行
复制
var resultWithContactKey = tempResultByContainingContacts[true]
    .SelectMany(x => x.Contacts
        .Select(contact => new ResultModel
        {
            Key1 = x.Key1,
            Key2 = x.Key2,
            ContactKey = contact.id
        }));

最后,将两个子集合连接起来以创建result

代码语言:javascript
运行
复制
var result = resultWithoutContactKey
    .Concat(resultWithContactKey)
    .ToList();

注意:

  • 通过定义两个子集合并将它们连接起来,得到的顺序将与原始顺序不同。
  • 好的命名约定很重要。我试图选择一些描述性的名字,但不得不承认,这是很困难的,特别是对于查找表。希望你能找到更合适的东西。

一个接一个的问题更新建议

除了添加一行来验证.Select()之外,我没有对新的主[...].baseTable5 != null块中的逻辑进行任何更改。

我建议拆分临时子集合并创建结果子集合,遵循我前面描述的模式:

代码语言:javascript
运行
复制
var tempResult = _context.baseTable1
    .Where(h => h.id == Id)
    .Select(lev => new 
    { 
        Contact = 
            lev.baseTable2 != null && 
            lev.baseTable2.baseTable3 != null && 
            lev.baseTable2.baseTable3.baseTable5 != null && // this line was added
            lev.baseTable2.baseTable3.baseTable5
                .Any(h => h.contact != null) 
            ? lev.baseTable2.baseTable3.baseTable5
                .Where(h => h.contact != null)
                .GroupBy(h => h.contact)
                .Select(c => c.FirstOrDefault().contact) 
            : null, 
        Key1 =
            lev.office != null 
            ? lev.office.id, 
            : null, 
        Key2 =
            lev.baseTable2 != null && 
            lev.baseTable2.baseTable3 != null && 
            lev.baseTable2.baseTable3.baseTable4 != null 
            ? lev.baseTable2.baseTable3.baseTable4.id 
            : null
        })
    .ToList();

var tempResultByContainingContacts = tempResult
    .ToLookup(x => x.Contact != null && x.Contact.Any());
    
var resultWithoutContactKey = tempResultByContainingContacts[false]
    .Select(x => new FinalModel
    {
        Key1 = x.Key1,
        Key2 = x.Key2
    });

var resultWithContactKey = tempResultByContainingContacts[true]
    .SelectMany(x => x.Contact
        .Select(contact => new FinalModel
        {
            ContactKey = contact.id,
            Key1 = x.Key1,
            Key2 = x.Key2
        }));

var result = resultWithoutContactKey
    .Concat(resultWithContactKey)
    .ToList();

return result;

如果可能的话,我还建议简化新的主.Select()块。不过,我不确定在查询数据库时是否可以翻译?.符号。如果不能,请忽略以下建议:

代码语言:javascript
运行
复制
var tempResult = _context.baseTable1
    .Where(h => h.id == Id)
    .Select(lev => new 
    { 
        Contact = lev.baseTable2?.baseTable3?.baseTable5?
            .Where(h => h.contact != null)
            .GroupBy(h => h.contact)
            .Select(c => c.FirstOrDefault().contact), 
        Key1 = lev.office?.id, 
        Key2 = lev.baseTable2?.baseTable3?.baseTable4?.id
    })
    .ToList();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72897523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档