Linq/EF, Eager loading и GROUP BY
У меня проблемы с GROUP BY и яростная загрузка. Я пытаюсь объяснить, что я делаю.
Я запрашиваю datacontext ctx для событий
Класс событий имеет следующие свойства
string Description
DateTime Date
bool IsDeleted
Guid SubjectId
string Title
DateTime Created
Guid ForProjectId
Person TriggeredBy
List<Guid> Targets
Есть muttiple события с одним и тем же SubjectId, и я бы хотел, чтобы в итоге появились события с уникальными SubjectIds, которые являются самыми новыми в группе. Я получаю следующий запрос.
var events = from x in
(from e in ctx.Events
.Include("TriggeredBy")
.Include("Targets")
group e by e.SubjectId
into g
select new
{
GroupId = g.Key,
EventsWithSameSubjectId = g,
}
)
select x.EventsWithSameSubjectId
.OrderByDescending(y => y.Created).FirstOrDefault();
Скомпилировать запрос и вернуть правильный результат. Но включенные свойства всегда равны нулю.
Когда я убираю запрос, чтобы увидеть, правильно ли загружена загрузка эго.
var events = (from e in ctx.Events.OfType<DataNotificationEvent>()
.Include("TriggeredBy")
.Include("Targets")
select e).ToList();
Это возвращает события со всеми включенными свойствами.
Является ли это известной проблемой/ошибкой с Linq/EF или есть ли способ избавиться от этой ошибки.
Привет
Винсент Оттенс
Ответы
Ответ 1
Вы проецируете анонимный тип, поэтому Include()
не будет работать так. Потому что то, что вы сделали с group
и проецируемым в анонимный тип, заключается в изменении формы запроса. Это бросает нетерпеливую нагрузку. Чтение этой статьи может помочь.
Ответ 2
Thnx для быстрого ответа. Ты указал мне в правильном направлении. Вот решение, которое я придумал:
using MyFunc = Func<ExtendedCoreContext, Guid, IQueryable<DataNotificationEvent>>;
private static readonly MyFunc GetMentionsNewCompiledQuery =
CompiledQuery.Compile<ExtendedCoreContext, Guid, IQueryable<DataNotificationEvent>>(
(ctx, personId) => ((ObjectQuery<DataNotificationEvent>)(
from x in (
from e in ctx.Events.OfType<DataNotificationEvent>()
group e by e.SubjectId
into g
select g.OrderByDescending(p => p.Created).FirstOrDefault()
)
orderby x.Created descending
where x.Targets.Any(t => t.Id == personId)
select x
))
.Include(EntityProperties.Event.TriggeredBy)
.Include(EntityProperties.DataNotificationEvent.Targets)
);