实体框架包括vs其中

时间:2011-10-11 20:23:44

标签: c# sql entity-framework azure-sql-database

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

我有一个GUID字符串,用于标识特定用户(此代码中为wlid)。我希望得到IEnumerable标识的用户OptiDashboards的所有wlid

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

3 个答案:

答案 0 :(得分:4)

您可能误解了Include函数实际执行的操作。选项1纯粹是一种查询语法,它对实体框架返回的内容没有影响。使用Include函数的选项2在返回查询结果时指示实体框架 Eagerly Fetch 来自数据库的相关行。

因此选项1将导致一些连接,但查询的“选择”部分将仅限于OptiDashboards表。

选项2也会导致连接,但在这种情况下,它将返回所有所包含的表的结果,这显然会带来更多的性能损失。但与此同时,结果将包括您需要的所有相关实体,避免[可能]需要更多往返数据库。

答案 1 :(得分:0)

我认为Include将呈现为joins,您将能够从您的用户对象中的那些表中访问数据(Eager Loading the properties)。

Any查询将呈现为exists,而不会使用其他表格中的信息加载用户对象。

为了获得最佳性能,如果您不需要其他信息,请使用Any查询

答案 2 :(得分:0)

正如已经指出的那样,第一种选择几乎肯定会表现得更好,仅仅因为它会检索更少的信息。除此之外,我想指出你也可以用这种方式编写查询:

var dashboards =
    from u in db.OptiUsers where u.WinLiveIDToken == wlid
    from im in u.IdentityMaps
    from d in im.UserGroup.OptiDashboards
    select d;

我希望上述内容的表现与第一个选项类似,但您可能(或可能不)更喜欢上述表格。