![]() |
寂寞的牛肉面 · 润物无声帮教戒毒———《司法为民好榜样》代表 ...· 1 年前 · |
![]() |
爽快的大熊猫 · 汤姆林森称赞好兄弟哈卷单飞成功表示深感骄傲_ ...· 1 年前 · |
![]() |
留胡子的番茄 · 《偶像大师灰姑娘女孩鉴赏革命》9月28日新D ...· 1 年前 · |
![]() |
叛逆的沙滩裤 · 荧光显影ETS微创技术治疗手汗症- 知乎· 1 年前 · |
![]() |
热心肠的雪糕 · 天柱山瓜蔞籽- Top ...· 1 年前 · |
我有LINQ查询,在这个查询中,我必须使用一个结果集进行响应,这取决于内部字段集合。我已经通过LINQ查询完成了这件事,然后是一个foreach,但是我想要避免foreach循环,并通过
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
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
}).ToList().SelectMany(x =>
if (!x.Contact.Any())
return new List<FinalModel> { new FinalModel { Key1 = x.Key1, Key2 = x.Key2 } };
return x.Contact.Select(contact => new FinalModel()
ContactKey = contact.id,
Key1 = x.Key1,
Key2 = x.Key2
});
您可以使用
SelectMany
来扁平数组,例如:
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,
return x.Contacts.Select(contact => new ResultModel()
Key1 = x.Key1,
Key2 = x.Key2,
ContactKey = contact.id,
}).ToArray();
.ToList();
在
SelectMany
中,将检查是否设置了联系人列表;如果没有,则返回单个项目,否则将返回每个联系人的项目。
我会发现,为没有联系人键的结果创建一个
ResultModel
子集合和用一个联系人键为结果创建另一个子集合更容易读。我怀疑随着时间的推移,这种方法也会比一个Linq表达式更容易维护。
您可以首先对临时结果进行分组,以便一个子集合包含
临时结果而没有
contacts
,而另一个子集合包含
临时结果(
E 210E 111
联系人
E 212
)。
通过使用具有适当条件的包含联系人的 .ToLookup() ,很容易获得这种分组。
var tempResultByContainingContacts = tempResultSet
.ToLookup(x => x.Contacts != null && x.Contacts.Any());
(我添加了
&& x.Contacts.Any()
条件。如果这不适合您的用例,您可以忽略它。)
在定义了查找表之后,您有:
tempResultByContainingContacts[false]
中的
tempResultByContainingContacts[true]
现在,可以根据临时结果计算一个结果子集合,而不需要 contacts。
var resultWithoutContactKey = tempResultByContainingContacts[false]
.Select(x => new ResultModel
Key1 = x.Key1,
Key2 = x.Key2
});
以及基于临时结果和 contacts生成的子集合。
var resultWithContactKey = tempResultByContainingContacts[true]
.SelectMany(x => x.Contacts
.Select(contact => new ResultModel
Key1 = x.Key1,
Key2 = x.Key2,
ContactKey = contact.id
}));
最后,将两个子集合连接起来以创建
result
。
var result = resultWithoutContactKey
.Concat(resultWithContactKey)
.ToList();
注意:
一个接一个的问题更新建议
除了添加一行来验证
.Select()
之外,我没有对新的主
[...].baseTable5 != null
块中的逻辑进行任何更改。
我建议拆分临时子集合并创建结果子集合,遵循我前面描述的模式:
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()
块。不过,我不确定在查询数据库时是否可以翻译
?.
符号。如果不能,请忽略以下建议:
var tempResult = _context.baseTable1
.Where(h => h.id == Id)
.Select(lev => new
Contact = lev.baseTable2?.baseTable3?.baseTable5?
.Where(h => h.contact != null)
![]() |
叛逆的沙滩裤 · 荧光显影ETS微创技术治疗手汗症- 知乎 1 年前 |