简体   繁体   English

是否有更清晰简洁的方式用更好的LINQ来表达这种说法?

[英]Is there a more clear and concise way to express this statement with better LINQ?

I have two collections of elements. 我有两个元素集合。 I am trying to take all elements in the first collection which have a matching ID in the second collection and run the CopyToDomain method against the matching elements. 我试图在第一个集合中获取第二个集合中具有匹配ID的所有元素,并针对匹配元素运行CopyToDomain方法。

The following code works fine, but I was a bit surprised by its verbosity. 以下代码工作正常,但我对它的详细程度感到有些惊讶。 ReSharper isn't recommending anything here, but I was wondering if doing an intersection of the two collections and then mapping the method over the elements would be more clear? ReSharper在这里没有推荐任何东西,但我想知道是否在这两个集合中进行交集然后将方法映射到元素上会更清楚吗? Would you make that change, or should I stop fussing and leave this as it is? 你会做出这样的改变吗,还是我应该停止烦恼并保持原样?

Task task = new Task();
IList<TaskAttributeDto> taskAttributeDtos = new List<TaskAttributeDto>();
taskAttributeDtos.Add(new TaskAttributeDto{ ID = 1});
taskAttributeDtos.Add(new TaskAttributeDto{ ID = 2});

foreach (TaskAttributeDto taskAttributeDto in taskAttributeDtos)
{
    TaskAttribute matching = task.TaskAttributes.FirstOrDefault(t => t.ID == taskAttributeDto.ID);
    if (matching != null)
    {
        taskAttributeDto.CopyToDomain(matching);
    }
}

What you're doing is basically a join, so you can use the Linq join syntax: 你正在做的基本上是一个连接,所以你可以使用Linq连接语法:

var matches =
    from dto in taskAttributesDtos
    join attribute in task.TaskAttributes on dto.ID equals attribute.ID
    select new { dto, attribute};

foreach (var m in matches)
    m.dto.CopyToDomain(m.attribute);
foreach(TaskAttributeDto taskAttributeDto in taskAttributeDtos.Where(t1 => TaskAttributes .Any(t2 => t2.Id == t1.Id)))
{
    taskAttributeDto.CopyToDomain(taskAttributeDto);
}

If you're concerned about the readability of query syntax, you can try using method syntax: 如果您担心查询语法的可读性,可以尝试使用方法语法:

var matches = taskAttributesDtos.Join(task.TaskAttributes,
                                      a => a.ID,
                                      b => b.ID,
                                      (a, b) => new { dto = a, attribute = b } );

foreach (var m in matches)
    m.dto.CopyToDomain(m.attribute);
task.TaskAttributes.Where(t => taskAttributeDtos.Select(d => d.ID).Contains(t.ID))
    .ToList()
    .ForEach(t => taskAttributeDtos.First(d => d.ID == t.ID).CopyToDomain(t));

The original code finds the first match. 原始代码找到第一个匹配项。 A join finds all matches, and a group join allows you to pick a winner from each matching group. 联接查找所有匹配项,组联接允许您从每个匹配组中选择一个获胜者。

var matches =
    from dto in taskAttributesDtos
    join attribute in task.TaskAttributes
      on dto.ID equals attribute.ID
      into attributeGroup  //into clause causes GroupJoin to be called.
    select new { dto, attribute = attributeGroup.First() };

foreach (var m in matches)
    m.dto.CopyToDomain(m.attribute);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM