实体框架包括vs where
本文关键字:where vs 包括 框架 实体 | 更新日期: 2023-09-27 18:11:04
我的数据库结构是这样的:一个OptiUser
通过IdentityMap
表属于多个UserGroup
,这是一个匹配表(多对多),附加了一些额外的属性。每个UserGroup
有多个OptiDashboard
。
我有一个GUID字符串,用于标识特定的用户(本代码中的wlid
)。我想获得由wlid
标识的用户的所有OptiDashboards
的IEnumerable
。
这两个Linq-to-Entities查询哪个是最有效的?它们在后端以相同的方式运行吗?
另外,我可以缩短选项2的Include
语句到.Include("IdentityMaps.UserGroup.OptiDashboards")
吗?
using (OptiEntities db = new OptiEntities())
{
// option 1
IEnumerable<OptiDashboard> dashboards = db.OptiDashboards
.Where(d => d.UserGroups
.Any(u => u.IdentityMaps
.Any(i => i.OptiUser.WinLiveIDToken == wlid)));
// option 2
OptiUser user = db.OptiUsers
.Include("IdentityMaps")
.Include("IdentityMaps.UserGroup")
.Include("IdentityMaps.UserGroup.OptiDashboards")
.Where(r => r.WinLiveIDToken == wlid).FirstOrDefault();
// then I would get the dashboards through user.IdentityMaps.UserGroup.OptiDashboards
// (through foreach loops...)
}
您可能误解了Include
函数的实际作用。选项1是纯粹的查询语法,对实体框架返回的内容没有影响。选项2,使用Include
函数指示实体框架在返回查询结果时从数据库中急切地获取相关行。
因此选项1将导致一些连接,但是查询的"select"部分将被限制在OptiDashboards
表中。
选项2也会导致连接,但是在这种情况下,它将返回来自所有包含的表的结果,这显然会带来更多的性能损失。但同时,结果将包括您需要的所有相关实体,避免了[可能]需要更多的往返数据库。
我认为Include
将呈现为joins
,你将能够访问这些表中的数据在你的用户对象(急于加载属性)。
Any
查询将呈现为exists
,而不会从其他表加载用户对象的信息。
Any
查询
正如已经指出的那样,第一个选项几乎肯定会执行得更好,因为它将检索较少的信息。除此之外,我还想指出,您还可以这样编写查询:
var dashboards =
from u in db.OptiUsers where u.WinLiveIDToken == wlid
from im in u.IdentityMaps
from d in im.UserGroup.OptiDashboards
select d;
我希望上面的执行与第一个选项类似,但您可能(也可能不)更喜欢上面的形式。