关于收集的哪个条款

我正在使用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) 

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

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

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

有任何想法吗?

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

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

但如果我把你的要求写到信中,它仍然不能做你想要的。 您希望包含住宿的位置,即部分加载导航属性。 当要将实体序列化并发送到一个包中的(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(); 

现在,如果你遍历context.Destinations.Where(d => d.Country == "USA")你会发现他们的住所加载了“ >5 ”。 可能是因为此时EF执行了关系修正。 (延迟加载已禁用,因为延迟加载将完全加载导航属性)。

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

通常,这是使用在获取实体时加载的导航属性完成的。

但是,您也可以使用以下方法执行此操作:

 (from d in baga.Locations from l in Lodgings where (d.LocationID == l.destination_id) where (d.Country = 'usa' && (l.MilesFromNearestAirport > 5 || l.MilesFromNearestAirport == null)) select d) .ToList(); 

我希望这会对你有所帮助。

如何使用LINQ join?

  var res = from d in context.Destinations join l in context.Lodgings on d.LocationID equals l.destination_id where (l.MilesFromNearestAirport > 5 || l.MilesFromNearestAirport == null) && d.Country = "usa" select new { Destination = d, Location = l }