Linq,模拟连接和Include方法

时间:2009-12-12 20:11:40

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

我正在研究与......有关的问题 Join and Include in Entity Framework

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

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查询中的“Include”调用不会加载对象。如果我在LINQ查询后显式调用“Load()”,则对象加载。

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

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

感谢。

修改

我已将问题追溯到使用多个来自子句

这有效......

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;

来自子句时,基本上会忽略包含调用。有谁知道这方面的工作?

修改2

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

EG。这有效....

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就是解决方案。

1 个答案:

答案 0 :(得分:4)

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

  1. 您可以围绕查询打包包含,请参阅Tip 22 - How to make include really include
  2. 或者您可以在select子句中获得所需的一切,让关系fixup为您完成工作。即。

    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);  
    
  3. 现在结果是属性实体的枚举,但每个都加载了phyAddress,作为phyAddress的初始请求的副作用,以及EF的关系修正。