Как объединить результаты из двух разных наборов в LINQ? - PullRequest
0 голосов
/ 29 апреля 2010

Я получаю некоторые данные о клиентах в своей базе данных с помощью этого метода:

    public List<KlientViewModel> GetListOfKlientViewModel()
    {
        List<KlientViewModel> list = _klientRepository.List().Select(k => new KlientViewModel
            {
                Id = k.Id,
                Imie = k.Imie,
                Nazwisko = k.Nazwisko,
                Nazwa = k.Nazwa,
                SposobPlatnosci = k.SposobPlatnosci,
            }).ToList();
        return list;
    }

но у меня также есть другой метод, который подсчитывает значение для дополнительного поля в KlientViewModel - поле с именем 'Naleznosci'.

У меня есть другой метод, который подсчитывает значение для этого поля на основе идентификаторов клиентов, это выглядит так:

public Dictionary<int, decimal> GetNaleznosc(List<int> klientIds)
{
    return klientIds.ToDictionary(klientId => klientId, klientId => (from z in _zdarzenieRepository.List()
         from c in z.Klient.Cennik
         where z.TypZdarzenia == (int) TypyZdarzen.Sprzedaz && z.IdTowar == c.IdTowar && z.Sprzedaz.Data >= c.Od && (z.Sprzedaz.Data < c.Do || c.Do == null) && z.Klient.Id == klientId
         select z.Ilosc*(z.Kwota > 0 ? z.Kwota : c.Cena)).Sum() ?? 0);
}

Итак, я хочу соединить данные из метода GetNaleznosc с данными, сгенерированными в методе GetListOfKlientViewModel. Я называю GetNaleznosc следующим образом:

GetNaleznosc(list.Select(k => k.Id).ToList())

но не знаю, что делать дальше.

1 Ответ

0 голосов
/ 29 апреля 2010

Получив словарь:

var dict = GetNaleznosc(list.Select(k => k.Id).ToList());

Теперь вы можете эффективно искать десятичное значение Naleznosci для данного клиента:

foreach (var k in list)
    k.Naleznosci = dict[k.Id];

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

Кстати, в вашей функции, которая создает словарь, вы заставляете его принимать List<int>, но тогда все, что вы делаете, это вызываете ToDictionary для него, что требует только IEnumerable<int>. Поэтому измените тип параметра на этот, и тогда вы сможете вызвать его:

var dict = GetNaleznosc(list.Select(k => k.Id));

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

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

public decimal GetNaleznosc(int klientId)
{
    return (from z in _zdarzenieRepository.List()
      from c in z.Klient.Cennik
      where z.TypZdarzenia == (int) TypyZdarzen.Sprzedaz && z.IdTowar == c.IdTowar && z.Sprzedaz.Data >= c.Od && (z.Sprzedaz.Data < c.Do || c.Do == null) && z.Klient.Id == klientId
      select z.Ilosc*(z.Kwota > 0 ? z.Kwota : c.Cena)).Sum() ?? 0);
}

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

public List<KlientViewModel> GetListOfKlientViewModel()
{
    return  _klientRepository.List().AsEnumerable().Select(k => new KlientViewModel
        {
            Id = k.Id,
            Imie = k.Imie,
            Nazwisko = k.Nazwisko,
            Nazwa = k.Nazwa,
            SposobPlatnosci = k.SposobPlatnosci,
            Naleznosci = GetNaleznosc(k.Id)
        }).ToList();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...