关于收集的哪个条款

atr*_*eon 5 .net c# linq-to-entities entity-framework

我正在使用Julie Lerman的DbContext书中的BAGA代码.我想在LINQ中重新创建以下SQL查询,并将结果放在List集合中,并且遇到问题. http://learnentityframework.com/downloads/

SELECT * FROM baga.Locations d
LEFT JOIN Lodgings l ON d.LocationID = l.destination_id
WHERE d.Country = 'usa'
AND (l.MilesFromNearestAirport > 5 or l.MilesFromNearestAirport is null)
Run Code Online (Sandbox Code Playgroud)

所以,用英语,获取在美国的所有地点(目的地),并包括所有相关的住宿,其中MilesFromNearestAirport> 5

语法不能编译,但我希望有类似于下面的内容

var dests = context.Destinations
  .Where(d => d.Country == "USA" && d.Lodgings.Where(l => l.MilesFromNearestAirport > 5))
  .Select(d => d)
  .ToList();
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Ger*_*old 7

正如@Sampath所说,这通常是通过导航属性完成的,但我相信他的代码并不完全符合您的要求.这(我认为)更接近:

var dests = context.Destinations
           .Where(d => d.Country == "USA")
           .Select(d => 
               new { d,
                     RemoteLodgings = d.Lodgings
                         .Where(l => l.MilesFromNearestAirport > 5)}
           .ToList();
Run Code Online (Sandbox Code Playgroud)

但如果我把你的要求写到信中,它仍然不能做你想要的.您希望包含住宿的位置,即部分加载导航属性.当要将实体序列化并发送到一个包中的(Web)客户端时,这可能很方便.(虽然上面的方法也可以).

但是可以使用部分加载的导航属性创建集合.

这本书,在第40页,显示了如何部分加载单个实体的导航属性(简而言之:context.Entry(entity).Collection(e => e.Children).Query().Where(condition).但正如所说,这只是一个实例.对于一组实体来说,这不是最好的方法.

有趣的是(作为我的同事发现),您可以通过分别将所需的集合元素加载到上下文中来轻松地为实体集合执行此操作:

var lodgings = context.Lodgings
              .Where(l => l.MilesFromNearestAirport > 5 
                       && l.Destination.Country == "USA")
              .ToList();
Run Code Online (Sandbox Code Playgroud)

现在,如果你循环通过,context.Destinations.Where(d => d.Country == "USA")你会看到他们的住所装满了" >5".可能是因为此时EF执行了关系修复.(延迟加载已禁用,因为延迟加载将完全加载导航属性).

编辑(在你的评论之后)
当你说它有点像黑客时,我完全同意.实际上,我首先忘了提到它.问题是当延迟加载碰巧被不知道代码是什么的人激活时,整个机制崩溃了.我不喜欢以不明显的方式依赖于状态的代码.所以我总是喜欢第一种方法.