LINQ to Objects Объедините две коллекции, чтобы установить значения в первой коллекции - PullRequest
20 голосов
/ 15 ноября 2011

У меня есть следующий запрос Entity Framework:

var results = from r in db.Results
              select r;

Я использую AutoMapper для сопоставления с другим типом:

var mapped = Mapper.Map<IEnumerable<Database.Result>, IEnumerable<Objects.Result>>(results);

В моем типе Objects.Result у меня естьсвойство называется причиной, которая не приходит из базы данных.Он исходит из другого источника, который мне нужно заполнить обратно в мой сопоставленный тип:

var reasons = new List<Reason>
{
    new Reason { Id = 1, Reason = "asdf..." }
};

Мне нужно объединить причины с моей сопоставленной коллекцией и установить свойство Reason в моей сопоставленной коллекции, используя значение измоя коллекция рассуждений.Возможно ли это?

 // need something like this:
 mapped = from m in mapped
          join r in reasons on m.Id equals r.Id
          update m.Reason = r.Reason
          select m;

Очевидно, что приведенный выше код не компилируется, но есть ли код, который я могу написать, который делает то, что я хочу?

Ответы [ 3 ]

24 голосов
/ 15 ноября 2011

Сделайте мутацию в цикле.Оптимально, Linq должен быть свободен от мутаций в коллекции, с которой он работает.Используйте Linq, чтобы фильтровать, упорядочивать, проецировать ваши данные, использовать традиционные методы для изменения.

var joinedData = from m in mapped 
                 join r in reasons on m.Id equals r.Id 
                 select new { m, r };

foreach (var item in joinedData)
{
    item.m.Reason = item.r.Reason;
}
9 голосов
/ 20 октября 2015

Это может сэкономить много вашего времени.Ниже приведен код для объединения двух коллекций и установки значения свойства первой коллекции.

class SourceType
{
    public int Id;
    public string Name;
    public int Age { get; set; }
    // other properties
}

class DestinationType
{
    public int Id;
    public string Name;
    public int Age { get; set; }
    // other properties
}
    List<SourceType> sourceList = new List<SourceType>();
    sourceList.Add(new SourceType { Id = 1, Name = "1111", Age = 35});
    sourceList.Add(new SourceType { Id = 2, Name = "2222", Age = 26});
    sourceList.Add(new SourceType { Id = 3, Name = "3333", Age = 43});
    sourceList.Add(new SourceType { Id = 5, Name = "5555", Age = 37});

    List<DestinationType> destinationList = new List<DestinationType>();
    destinationList.Add(new DestinationType { Id = 1, Name = null });
    destinationList.Add(new DestinationType { Id = 2, Name = null });
    destinationList.Add(new DestinationType { Id = 3, Name = null });
    destinationList.Add(new DestinationType { Id = 4, Name = null });


    var mapped= destinationList.Join(sourceList, d => d.Id, s => s.Id, (d, s) =>
    {
        d.Name = s.Name;
        d.Age = s.Age;
        return d;
    }).ToList();
0 голосов
/ 15 ноября 2011

Один метод грубой силы был бы: -

foreach(var m in mapped)
{
    m.Reason = reasons.Single(r=> r.Id == m.Id).Reason;
}

На самом деле, это реализация очень близка к вашему псевдокоду.

...