Is there a clearer and more concise way to express this statement better than LINQ?

I have two collections of elements. I am trying to take all the elements in the first collection that have the same identifier in the second collection and run the CopyToDomain method against the corresponding elements.

The following code works fine, but I was a bit surprised at its verbosity. ReSharper does not recommend anything here, but I was wondering if it would be clearer to perform the intersection of two collections and then display the method on the elements? Would you make this change, or should I stop fussing and leave it 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); } } 
+4
source share
5 answers

What you do is basically a join, so you can use the Linq join syntax:

 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); 
+11
source
 foreach(TaskAttributeDto taskAttributeDto in taskAttributeDtos.Where(t1 => TaskAttributes .Any(t2 => t2.Id == t1.Id))) { taskAttributeDto.CopyToDomain(taskAttributeDto); } 
+2
source

If you are concerned about the readability of the query syntax, you can try using the 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); 
+2
source
 task.TaskAttributes.Where(t => taskAttributeDtos.Select(d => d.ID).Contains(t.ID)) .ToList() .ForEach(t => taskAttributeDtos.First(d => d.ID == t.ID).CopyToDomain(t)); 
+1
source

The source code finds the first match. The combination finds all matches, and the group connection allows you to choose a winner from each suitable 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); 
0
source

All Articles