繁体   English   中英

在Entity Framework上预先加载导航属性

[英]Eager load navigation properties on Entity Framework

我一直在寻找解决我的问题的互联网,但却找不到任何有效的方法。

我有一个查询选择一个新的DTO,如下所示:

List<myDTO> query = (from c in db.Customers                 
           .Include(x => x.Orders)
            where customerId = 5
            select new myDTO
{
 Customer = c,
...
}).ToListAsync();

foreach (var custDto in query)
{
   //this is lazy loaded
   var customerOrder = custDto.Customers.Orders;
}

我的问题是当我尝试导航到query.Customers.Orders它是懒惰加载。 我想急切加载Orders属性,以便在循环访问客户时不会多次访问数据库。 我认为包含会急切加载导航属性。

我知道我可以在myDTO中添加一个订单属性并以这种方式加载它,但我很好奇是否可能采用上述方式。

谢谢!

我不确定你是否可以通过延迟加载仍然启用加载属性。 如果您愿意仅为CustomersOrders属性或整个上下文禁用延迟加载,那么它应该按照您呈现的方式工作。

您可以通过从Orders属性中删除virtual关键字来完成此操作,或者通过添加以下命令将其关闭以用于整个dbContext:

     this.Configuration.LazyLoadingEnabled = false;

到您的dbContext构造函数。 然后急切加载您呈现它的方式应该工作正常。

但是,请记住,您将来必须始终加载该属性(或所有导航属性,具体取决于您采用的方法)。

如您所知, 当查询结果是投影时 ,急切加载( Include )不起作用。 这有点令人讨厌,在像你这样的情况下,当结果包含完整的实体时,我真的不明白为什么这些实体没有启用导航属性Include ed。

无论如何,这是一个限制,你必须找到一个解决办法。 正如你所说,包括Orders = c.Orders这样的属性是可能的。 你可以做的另一件事是

db.Configuration.LazyLoadingEnabled = false;
var intermed = (from c in db.Customers                 
                where customerId = 5
                select new
                {
                    Customer = c,
                    ...
                    Orders = c.Orders
                }).ToListAsync();
var dtos = intermed.Select(x => new myDTO
                                {
                                    Customer = x.Customer,
                                    ...
                                }).ToList();

您会注意到myDTO.Customer.Orders已填充,因为当上下文包含相关实体(也称为关系修正 )时,EF会自动填充导航属性。 必须禁用延迟加载,因为myDTO.Customer.Orders未在内部标记为已加载,因此解决它仍会触发延迟加载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM