Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

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.

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? 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);
    }
}
like image 398
Sean Anderson Avatar asked Dec 04 '22 13:12

Sean Anderson


2 Answers

What you're doing 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);
like image 107
Thomas Levesque Avatar answered Jan 19 '23 00:01

Thomas Levesque


foreach(TaskAttributeDto taskAttributeDto in taskAttributeDtos.Where(t1 => TaskAttributes .Any(t2 => t2.Id == t1.Id)))
{
    taskAttributeDto.CopyToDomain(taskAttributeDto);
}
like image 33
asr Avatar answered Jan 18 '23 22:01

asr