Заявления Linq нуждаются в оптимизации - PullRequest
1 голос
/ 14 декабря 2010

Я написал следующий код:

//get the user from the DB
var tmpuser = _db.aspnet_Users.First(q => q.UserName == user.Identity.Name);

//list the direct connections to Verbond
List<Verbond> verb1 = tmpuser.UsersVerbondens
                             .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam)
                             .Select(q => q.Verbond)
                             .ToList();

//list the connected Facturatieverbonden
List<FacturatieVerbonden> verb2 = tmpuser.UsersFacturatieVerbondens
                                         .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam)
                                         .Select(q => q.FacturatieVerbonden)
                                         .ToList();

//loop through the facturatieverbonden and add their verbonds to the first list
foreach (FacturatieVerbonden v in verb2) {
    verb1.AddRange(v.Verbonds);
}

//make a distinct list
List<Verbond> test = verb1.Distinct().ToList();

Итак, пользователи могут быть подключены к 0 или более facturatieverbonden, а также могут быть подключены к verbond.

A facturatieverbonden может иметь один или несколько verbond под собой.

Мне нужен список всех verbond, к которым пользователь подключен, напрямую или косвенно через facturatieverbonden.

Мой код работает, но я не думаю, что он очень эффективен.Есть какие-нибудь советы, как сделать его чище?

Ответы [ 2 ]

5 голосов
/ 14 декабря 2010

Ваш запрос не очень LINQy.Вот потенциальное улучшение:

           //list the direct connections to Verbond 
var test = (from q in tmpuser.UsersVerbondens
            where q.Schooljaar.Sch_Schooljaar == schooljaarparam
            select q.Verbond)
           //return distinct values
           .Union
           //list the connected Facturatieverbonden 
           (from q in tmpuser.UsersFacturatieVerbondens
            where q.Schooljaar.Sch_Schooljaar == schooljaarparam
            from v in q.FacturatieVerbonden.Verbonds
            select v)
           //return a List
           .ToList();

Делая ToList самым последним, что он делает, все вычисления можно выполнять в базе данных, избегая всех промежуточных списков.

0 голосов
/ 14 декабря 2010

Ваша проблема производительности здесь.Каждый вызов AddRange будет перечислять v.Verbonds, и каждый будет обходом базы данных.

//loop through the facturatieverbonden and add their verbonds to the first list 
foreach (FacturatieVerbonden v in verb2) { 
    verb1.AddRange(v.Verbonds); 
} 

Чтобы исправить это:

//query the connected Facturatieverbonden 
IQueryable<FacturatieVerbonden> verbQuery2 = tmpuser.UsersFacturatieVerbondens 
  .Where(q => q.Schooljaar.Sch_Schooljaar == schooljaarparam) 
  .Select(q => q.FacturatieVerbonden);

verb1.AddRange(verbQuery2.SelectMany(fv => fv.Verbonds));

Есть еще много места для снижения производительности, нопо крайней мере, это решает серьезную проблему.Вы можете легко наблюдать ускорение в 10 раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...