【问题标题】:Entity Framework - Select with or without relationships实体框架 - 选择有或没有关系
【发布时间】:2012-09-06 19:19:35
【问题描述】:

如果我有一组表,TableA、TableB、TableC 和 TableD,其中 TableA 与 TableB、TableC 和 TableD 具有一对多的关系。

有时我想返回整组 TableA、TableB、TableC 和 TableD。有时我只想返回 TableA。

目前我有以下内容:

TableA tableA;

if (includeRelationships)
{
    tableA = (from a in context.TableAs
                   .Include("TableBs")
                   .Include("TableCs")
                   .Include("TableDs")
              where a.Id = myId
              select a).SingleOrDefault();
}
else
{
    tableA = (from a in context.TableAs
              where a.Id = myId
              select a).SingleOrDefault();
}

// do stuff with tableA

这是唯一的方法吗?

编辑 - feanz 回答后的澄清:

这将作为 WCF 服务公开,因此它需要是单个数据库调用,可以是所有表或单个 TableA,因此不能选择延迟/延迟加载。

【问题讨论】:

    标签: entity-framework linq-to-entities


    【解决方案1】:

    因为 EF 默认支持延迟加载第二个例子:

     tableA = (from a in context.TableAs
              where a.Id = myId
              select a).SingleOrDefault();
    

    仍然会有 TableBs、TableCs 和 TableDs 作为您可以访问的参数。第一次访问这些参数时,EF 应该触发查询以获取适当的信息。这可能是一个性能问题并导致 N+1 问题,但是在某些情况下,正如您提到的那样,您可能不希望始终获取数据。

    EF Lazy Loading Info

    【讨论】:

    • 啊,可能应该补充说这是 WCF 服务的一部分,所以延迟加载并不是一个真正的选项
    • 根据您链接的文章,您必须在引用之前专门.Load(),它不会自动完成。无论哪种方式,它仍然意味着多次访问数据库而不是一次,因此它不适合此应用程序。
    【解决方案2】:

    做这样的事情

    var query = context.TableA;
    if (includeRelationships) 
    {
       query = query.Include("Tableb").Include("TableC").Include("TableD");
    }
    var tablea = query.SingleOrDefault();
    

    在这种情况下,您使用的扩展方法“Include”采用并返回 IQueryable。您可能想使用:

    query.Include(x => x.TableB)...
    

    将表达式作为参数的方法的重载。这样编译器将为您进行检查。如果您使用的是旧版本的 EF,您可能无法访问它。

    【讨论】:

      【解决方案3】:

      使用

      context.ContextOptions.LazyLoadingEnabled = true;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-27
        • 2019-04-15
        • 1970-01-01
        • 2018-07-19
        • 1970-01-01
        • 2016-06-08
        相关资源
        最近更新 更多