2013-09-29 2 views
1

У меня есть таблица People с около 1000 строк и таблица Dramas со 100 строками в SQL Azure. Эти два связаны с внешним ключом Drama.PersonId, так что каждый человек может иметь 0 или более драм.LINQ to Entities Выберите длительное время

Код ниже ведет себя так, как ожидалось, возвращая около 50 человек и связанные с ними недавние драмы. Однако для запуска требуется более 5 секунд (измеряется с помощью Stopwatch). Должно быть что-то неэффективное происходит?

var people = ctx.People 
    .Where(p => p.Dramas.Any(d => d.DateHappened >= startDate)) 
    .Select(p => new 
    { 
     p.FirstName, 
     p.LastName, 
     Dramas = p.Dramas.Where(d => d.DateHappened >= startDate).Select(d => new { d.Id, d.DramaType }) 
    }).AsEnumerable(); 
+0

попробуйте lazy loading, что может помочь! – Imran

+0

Мне нужна вся информация в следующей строке моего кода, поэтому я не думаю, что ленивая загрузка решит что угодно! – James

+0

, тогда попробуйте запустить raw sql-запрос. http://forums.asp.net/t/1896474.aspx проверить это может помочь вам! – Imran

ответ

0

Я сделал это намного быстрее, сначала извлекая все последние драмы, а затем отправляя отдельный запрос, чтобы получить людей. Он использует PredicateBuilder.

var dramasByPerson = ctx.Dramas.Where(d => d.DateHappened >= startDate) 
    .Select(d => new { d.PersonId, d.Id, d.DramaType }) 
    .ToLookup(d => d.PersonId); 

var predicate = dramasByPerson.Select(o => o.Key) 
    .Aggregate(
    PredicateBuilder.False<Person>(), 
    (current, personId) => current.Or(o => o.PersonId == personId) 
); 

var dictPeople = ctx.People.Where(predicate) 
    .Select(o => new { o.PersonId, o.LastName, o.FirstName }) 
    .ToDictionary(o => o.PersonId); 

var people = dramasByPerson.Select(o => new { 
    LastName = people[o.Key].LastName, 
    FirstName = people[o.Key].FirstName, 
    Dramas = o.Select(d => new { d.Id, d.DramaType }) 
});