实体框架包括vs where

本文关键字:where vs 包括 框架 实体 | 更新日期: 2023-09-27 18:11:04

我的数据库结构是这样的:一个OptiUser通过IdentityMap表属于多个UserGroup,这是一个匹配表(多对多),附加了一些额外的属性。每个UserGroup有多个OptiDashboard

我有一个GUID字符串,用于标识特定的用户(本代码中的wlid)。我想获得由wlid标识的用户的所有OptiDashboardsIEnumerable

这两个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...)
}

实体框架包括vs where

您可能误解了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;

我希望上面的执行与第一个选项类似,但您可能(也可能不)更喜欢上面的形式。