我有一个方法,它使用大量LINQ来设置和匹配Tuple<string, int>
列表中的某些值。
现在我仍然坚持使用两个相互嵌套的foreach循环,我认为可以将它们组合成一个巨大的LINQ查询。我想知道在优化过程中最好的方法是什么。
这是我正在谈论的功能:
private async void AddLocalChangesFromPendingOperations()
{
var pendingOperations = await this.operationsStorage.GetOperationsAsync();
var list = pendingOperations.
SelectMany(pendingOperation =>
pendingOperation.Settings, (pendingOperation, setting) =>
new { pendingOperation, setting })
.Where(a => a.setting.Key == "selection")
.Select(a => new Tuple<string, int>(
a.pendingOperation.DefinitionId,
Convert.ToInt32(a.setting.Value.ValueObject)))
.ToList();
foreach (var pendingChange in list)
{
var selection = await this.selectionsStorage.GetSelectionByIdAsync(pendingChange.Item2);
foreach (var selectionsViewModel in this.SelectionsList.Where(a => a.Name == selection.Name))
{
if (pendingChange.Item1 == "selection-add-animals")
{
selectionsViewModel.IsActive = true;
}
else if (pendingChange.Item1 == "selection-remove-animals")
{
selectionsViewModel.IsActive = false;
}
}
}
}
如果可能的话,我想在使用linq时优化最后两个foreach。我已经尝试了一些东西,但我仍坚持在当前列表中设置值...
我这样做:
this.SelectionsList = this
.SelectionsList
.Where(a => a.Name == selection.Name)
.SingleOrDefault(
a => pendingChange.Item1 == "selection-add-animals" ? a.IsActive = true : a.IsActive = false
);
答案 0 :(得分:1)
您可以执行以下操作:
this.SelectionsList = this.SelectionsList
.Where(a => a.Name == selection.Name)
.Select(a =>
{
a.IsActive = a.Name == selection.Name ? true:false;
return a;
}).ToList();
答案 1 :(得分:1)
通常,LINQ用于查询项目(语言集成Query
)。然而,你可以进行查询,然后在最后做一个foreach:
private async void AddLocalChangesFromPendingOperations()
{
var pendingOperations = await this.operationsStorage.GetOperationsAsync();
(await Task.WhenAll(pendingOperations
.SelectMany(pendingOperation =>
pendingOperation.Settings, (pendingOperation, setting) =>
new { pendingOperation, setting })
.Where(a => a.setting.Key == "selection")
.Select(a => Tuple.Create(a.pendingOperation.DefinitionId, Convert.ToInt32(a.setting.Value.ValueObject)))
.Select(async pendingChange => Tuple.Create(await this.selectionsStorage.GetSelectionByIdAsync(pendingChange.Item2)), pendingChange))
.SelectMany(tuple => this.SelectionsList.Where(a => a.Name == tuple.Item1.Name)
.Select(selectionsViewModel => Tuple.Create(selectionsViewModel, tuple.Item2))
.Select(tuple => Tuple.Create(tuple.Item1, tuple.Item2.Item1 == "selection-add-animals"))
.ToList()
.ForEach(tuple => tuple.Item1.IsActive = tuple.Item2);
}
这是否比原始实现更清晰可供讨论(我不认为),但这是一种方法。
注意:这是直接在编辑器中输入的,可能会有一些小的语法错误。