【问题标题】:Linq, emulating joins, and the Include methodLinq、模拟连接和 Include 方法
【发布时间】:2009-12-12 20:11:39
【问题描述】:

我正在调查一个与...相关的问题 Join and Include in Entity Framework

基本上,以下查询返回当前用户有权查看的“属性”对象列表 (ACL)。

IQueryable<Property> currPropList 
                = from p in ve.Property
                                .Include("phyAddress")
                                .Include("Contact")
                  from a in ve.ACLs
                  from u in ve.Account
                  from gj in ve.ObjectGroupJoin
                  where u.username == currUsername              // The username
                        && (a.Account.id == u.id                // The ACLs
                            && a.objType == (int)ObjectType.Group)
                        && (gj.ObjectGroup.id == a.objId        // The groups
                            && gj.objId == p.id)                // The properties
                  select p;

查询返回正确的属性列表,并且在大范围内工作正常。

但上述 linq 查询中的“包含”调用不会加载对象。如果我在 LINQ 查询之后显式调用“Load()”,则加载对象。

related SO question 表示“Include”调用与 where 子句之间可能存在冲突。怎么会这样?

但无论如何,我如何重新构建这个查询来加载“phyAddress”和“Contract”成员?具体来说,我只想加载 返回的 对象上的成员,而不是数据库中的所有“phyAddress”和“Contact”对象。

谢谢。

编辑

我已经追踪到使用多个 from 子句的问题

这行得通...

IQueryable<Property> currPropList 
            = from p in ve.Property
                            .Include("phyAddress")
              select p;

并且加载了“phyAddress”成员。

但这不起作用...

IQueryable<Property> currPropList 
            = from p in ve.Property
                            .Include("phyAddress")
              from a in ve.ACLs
              select p;

基本上,当有多个 from 子句时,Include 调用会被忽略。有谁知道解决这个问题的方法?

编辑 2

一种解决方法是将 IQueryable 结果转换为 ObjectQuery 并从中获取包含。但我想防止第二次往返我假设的数据库。

例如。这行得通....

IQueryable<Property> currPropList 
        = ((from p in ve.Property
          from a in ve.ACLs
          select p) as ObjectQuery<Property>).Include("phyAddress");

有没有办法只用一个查询来做到这一点?

编辑 3

由于延迟执行,没有第二次查询[http://blogs.msdn.com/charlie/archive/2007/12/09/deferred-execution.aspx。所以编辑 2 将是解决方案。

【问题讨论】:

  • 它只做一个 sql 查询。没有第二次往返。如果您不确定,您应该查看 SQL Server Profiler。

标签: c# .net linq entity-framework join


【解决方案1】:

这是 Include 的一个已知问题...如果您做的事情改变了查询的形状(即从 from),那么 Include 就会丢失,但是有足够简单的解决方法:

  1. 您可以将 include 包裹在查询周围,请参阅 Tip 22 - How to make include really include
  2. 或者您可以在 select 子句中获取您需要的所有内容,并让关系修复为您完成这项工作。即

    var x = from p in ve.Property  
            from a in ve.ACLs  
            select new {p,p.phyAddress};  
    
    var results = x.AsEnumerable().Select(p => p.p);  
    

现在结果是一个属性实体的枚举,但每个都加载了它的 phyAddress,这是对 phyAddress 的初始请求和 EF 关系修复的副作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多