Довольно сложный запрос LINQ to Entities - PullRequest
1 голос
/ 24 мая 2011

У меня есть две сущности, предположим, что они называются Контейнер и Запись. У них есть отношения master-child: «контейнер» может содержать много записей.

Таблица записей в базе данных имеет следующие столбцы:

  • Id
  • Дата
  • Container_Id
  • RecordType_Id

У сущности Record нет навигационных свойств, которые бы ссылались на Контейнер.

Я пишу запрос LINQ для моего репозитория, который будет извлекать ТОЛЬКО записи для контейнера, у которого самая последняя дата для каждого RecordType_Id. Все старые записи следует игнорировать.

Так, если в контейнере есть, скажем, 5 записей, по одной на каждый RecordType_Id, с датой 24 мая 2011 года. Но также есть еще 5 записей для каждого RecordType_Id, но с датой 20 мая 2011 года. Тогда только первые 5 с датой 24 мая будут получены и добавлены в коллекцию в контейнере.

Я придумал SQL-запрос, который делает то, что мне нужно (но, может быть, есть более эффективный способ?):

select t.*
from Records t
    inner join (
        select Container_Id, RecordType_Id, max(Date) AS MaxDate
        from Records
        group by Container_Id, RecordType_Id ) g
    on t.Date = g.MaxDate
        and t.Container_Id = g.Container_Id
        and t.RecordType_Id = g.RecordType_Id 
order by t.Container_Id 
    , t.RecordType_Id 
    , t.Date

Однако я изо всех сил пытаюсь перевести это в правильный запрос LINQ. EF уже сам генерирует довольно большой запрос только для загрузки сущностей, что не позволяет мне понять, какая часть этого SQL-запроса действительно относится к запросу LINQ.

Ответы [ 2 ]

1 голос
/ 24 мая 2011

Попробуйте использовать LinqPad, это поможет вам легко тестировать запросы linq.Даже против существующей модели EF (которая есть в вашем проекте).Визит http://www.linqpad.net/

1 голос
/ 24 мая 2011

с макушки головы:

var q = from c in Container
        from r in c.Records
        group r by r.RecordType.RecordType_Id into g
        select new
        {
            Container = c,
            RecordType_Id = g.Key,
            Records = from gr in g
                      let maxDate = g.Max(d => d.Date)
                      where gr.Date == maxDate
                      select gr
        };
...