linq - What would be a reasonably fast way to code this sql query in c#? -
i have sql query:
select sum(h.nbheures) heures h join heuresprojets hp on h.hpguid=hp.hpid join activitycodes ac on h.code=ac.activityid join maindoeuvre mdo on ac.activityid=mdo.codeguid hp.extraguid = '61e931c8-3268-4c9c-9ff5-ed0213d348d0' , mdo.notype = 1 it runs in less second, good. project uses linq entities data. (very similar sql) query terribly slow, taking more minute.
var result = (from hp in this.heuresprojets join h in ctx.heures on hp.hpid equals h.hpguid join ac in ctx.activitycodes on h.code equals ac.activityid join mdo in ctx.maindoeuvre on ac.activityid equals mdo.codeguid hp.extraguid == this.entityguid && mdo.notype == (int)sptype select h.nbheures).sum(); total = result; i tried using nested loops instead. it's faster still slow (~15 seconds).
foreach (heuresprojets item in this.heuresprojets) { foreach (heures h in ctx.heures.where(x => x.hpguid == item.hpid)) { if (h.activitycodes != null && h.activitycodes.maindoeuvre.firstordefault() != null && h.activitycodes.maindoeuvre.first().notype == (int)type) { total += h.nbheures; } } } am doing wrong? if there's no way optimize i'll call stored procedure keep logic in code.
edit
i modified query according ironman84's advice.
decimal total = 0; var result = (from hp in ctx.heuresprojets join h in ctx.heures on hp.hpid equals h.hpguid join ac in ctx.activitycodes on h.code equals ac.activityid join mdo in ctx.maindoeuvre on ac.activityid equals mdo.codeguid hp.extraguid == this.entityguid && mdo.notype == (int)sptype select h); if(result.any()) total = result.sum(x=>x.nbheures); this works. runs fast , gives decimal but:
1. it's not right value
2. result cached because returns exact same value different parameters.
from looking @ code i'm thinking query grabbing every single record tables you're joining on (hence long amount of time). i'm seeing using this.heuresprojets, i'm assuming collection of database objects had grabbed database (and that's why you're not using ctx.heuresprojets). collection, then, has been hydrated time join query. in case becomes linq-to-objects query, necessitating ef go , grab of other tables' records in order complete join.
assuming i'm correct in assumption (and let me know if i'm wrong), might want try out:
var result = (from hp in ctx.heuresprojets join h in ctx.heures on hp.hpid equals h.hpguid join ac in ctx.activitycodes on h.code equals ac.activityid join mdo in ctx.maindoeuvre on ac.activityid equals mdo.codeguid hp.extraguid == this.entityguid && mdo.notype == (int)sptype select h).sum(h => h.nbheures); total = result; also, if this.heuresprojets filtered list of specific objects, can add where clause of query make sure ids in this.heuresprojets.select(hp => hp.hpid)
Comments
Post a Comment