2011-11-14 4 views
15

Mam następujące zapytanie Entity Framework:LINQ to Objects Dołącz dwa zbiory ustawić wartości w pierwszej kolekcji

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

używam AutoMapper mapować do innego typu:

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

W mój typ Objects.Result, mam właściwość o nazwie reason, która nie pochodzi z bazy danych. Jest to pochodzący z innego źródła, że ​​muszę po prostu wypełnić z powrotem do mojego odwzorowanym typu:

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

muszę dołączyć uzasadnienie z moim odwzorowanym kolekcji i ustawić właściwość powodu w moim odwzorowanym kolekcji przy użyciu wartości z moich powodów kolekcja. czy to możliwe?

// 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; 

Oczywiście powyższy kod się nie komplikuje, ale czy istnieje kod, który mogę napisać, który robi to, czego chcę?

Odpowiedz

21

Dokonaj mutacji w pętli. Optymalnie, Linq powinien być wolny od mutacji w kolekcjach, przeciwko którym działa. Użyj Linq do filtrowania, porządkowania, projekcji danych, do modyfikacji przy użyciu tradycyjnych technik.

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; 
} 
+0

Dzięki. Wydaje mi się, że nie jest to wielkim hitem, ponieważ odkładam dane przed mapą, więc iteracja po raz drugi nie będzie problemem. – Dismissile

+0

Jeśli mierzysz i odkrywasz, że jest to wąskie gardło wydajności, wróć i zaadresuj to, możemy * dokonać * mutacji, jeśli * mamy *. Jednak nie zrobiłbym tego, dopóki nie wiedziałem, że to mnie spowalnia. –

+0

I strona około 10 przedmiotów na raz. Bardzo wątpię, że spowodowałoby to jakiekolwiek problemy z wydajnością :) – Dismissile

0

Jedna metoda brute force byłoby: - ​​

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

W rzeczywistości jest to realizacja jest dość blisko do pseudo-kodu.

5

To może zaoszczędzić wiele czasu. Poniższy kod dotyczy łączenia dwóch kolekcji i ustawiania wartości właściwości pierwszego zbioru.

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(); 
+1

Powinieneś wyjaśnić, co to jest. –