开发者

Linq statements need optimizing

I have written the following code:

//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();

So, Users can be connected to 0 or more facturatieverbonden and also can be connected to verbond.

A facturatieverbonden can have one or more verbond's under itself.

What I need is a list of all the verbond's the user is connected to, directly, or indirectly via the facturatieverbonden.

My code works but I don't think it's very efficient.开发者_运维知识库 Any hints on making it cleaner?


Your query isn't very LINQy. Here's a potential improvement:

           //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();

By making ToList the very last thing it does, the whole computation can be done in the database, avoiding all the intermediate lists.


Your performance problem is here. Each AddRange call will enumerate v.Verbonds, and each will be a database roundtrip.

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

To fix it:

//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));

There's still plenty of room to tighten the performance, but at least this address the gross problem. You could easily observe a 10 times speed up.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜