问题描述
如下两个表,都有数据[Table("Users")]publicclassUsers{publicUsers(){this.UserSources=newHashSet<UserScore>();}[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]publicintUserId{get;set;}publicstringName{get;set;}publicstringEmail{get;set;}publicvirtualICollection<UserScore>UserSources{get;set;}}[Table("UserScore")]publicclassUserScore{publicintId{get;set;}publicintUserId{get;set;}publicintScore{get;set;}}
请问哪一种方式性能更高方式1foreach(varuserincontext.User.ToList()){foreach(variteminuser.UserSources){Console.WriteLine(item.Score);}}
方式2varquery=(fromuincontext.Userjoinsincontext.UserScoreonu.UserIdequalss.UserIdselectnew{UserId=u.UserId,Score=s.Score}).ToList();foreach(varuserinquery){Console.WriteLine(user.Score);}
解决方案
解决方案二:
第一种,因为第一种没创建额外的匿名类,也没进行额外的join
解决方案三:
引用1楼starfd的回复:
第一种,因为第一种没创建额外的匿名类,也没进行额外的join
但我发现他每次都会去查数据库
解决方案四:
你这个是主外键……
解决方案五:
如果是这种主外键查询的话,那应该是第二种效率高,因为它只查一次
解决方案六:
引用3楼starfd的回复:
你这个是主外键……
我看好多用EF的,一般都会用一个virsual作为导航属性
解决方案七:
匿名类(委托)都是编译时就创建好了,跟性能没关系。但是不同类中相同的匿名类可能会冗余,因此可能会使程序集元数据增大,导致加载时占的内存更大如果是数据库中的数据,当然是第二种,第一种会将两个表中的所有数据全部取出来(表扫描),第二种则是将Linq翻译成sqljoin语句去数据库查询,数据库会自动选择最效率的方案查询(比如会优先使用键/索引),返回最后的结果集,很明显这个结果集是两个表数据的子集如果是内存数据,则两种差不多,Linq会稍慢(几乎可以忽略)
解决方案八:
也就是说查数据库还是建议用第二种方式,特别是在遍历一个实体又要取他的导航属性里的其他字段,是这样理解吧
解决方案九:
是的,因为让数据库返回一整个表的数据,负担是比较重的,反倒是把数据库最优秀的查询效率给避开了,它设计的那么多的键/索引以及各种高效稳定的查询算法,你都没用上。关系库最擅长的就是关联(系)查询,就像你上面要查导航属性一样