DetachedLazyLoadingWarning 的 Entity Framework Core 2.1 问题
Posted
技术标签:
【中文标题】DetachedLazyLoadingWarning 的 Entity Framework Core 2.1 问题【英文标题】:Entity Framework Core 2.1 problem with DetachedLazyLoadingWarning 【发布时间】:2019-04-13 23:25:14 【问题描述】:DetachedLazyLoadingWarning 出现异常:
为警告“Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning”生成错误:尝试在“DeliveryProxy”类型的分离实体上延迟加载导航属性“Product”。分离实体或使用“AsNoTracking()”加载的实体不支持延迟加载。通过将事件 ID 'CoreEventId.DetachedLazyLoadingWarning' 传递给 'DbContext.OnConfiguring' 或 'AddDbContext' 中的 'ConfigureWarnings' 方法,可以抑制或记录此异常。
在尝试使用 Entity Framework Code 2.1
查询 SQL 数据库时这是我的查询:
var orders =
_context
.Set<Order>()
.Where(v => v.CompanyId == companyId)
.Include(v => v.Details)
.ThenInclude(d => d.Delivery)
.ThenInclude(v => v.Product)
.OrderByDescending(v=> v.Details.FirstOrDefault().Delivery.Product.ProductId)
.ThenByDescending(v=> v.Details.FirstOrDefault().Delivery.Value)
.ThenByDescending(v => v.CreatedAt)
.Page(request.Page, request.RowsPerPage);
以下是实体和关系:
public class Order : IEntity<int>
public int CompanyId get; set;
public virtual ICollection<OrderDetails> Details get; set;
[Required]
public DateTimeOffset CreatedAt get; set;
[Key]
public int Id get; set;
public class OrderDetails : IEntity<int>
public int OrderId get; set;
public int DeliveryId get; set;
[ForeignKey(nameof(OrderId))]
public virtual Order Order get; set;
[ForeignKey(nameof(DeliveryId))]
public virtual Delivery Delivery get; set;
[Key]
public int Id get; set;
public class Delivery : IEntity<int>
[Required]
public int ProductId get; set;
public int Value get; set;
[ForeignKey(nameof(ProductId))]
public virtual Product Product get; set;
[Key]
public int Id get; set;
[Table("Products")]
public class Product : IEntity<int>
[Required]
public byte ProductCategoryId get; set;
public virtual ICollection<Delivery> Deliveries get; set;
[Key]
public int Id get; set;
看起来 Details.FirstOrDefault() 分离实体 Delivery。相同的解决方案适用于 Entity Framework 6。如何改进我的查询以仅使用一个查询从数据库中获取日期(抑制警告没有帮助)?
【问题讨论】:
【参考方案1】:您还应该看到很多Client evaluation logging 警告。目前客户端评估在显式/延迟加载时效果不佳。
在这种情况下,客户端评估的原因是排序方法中的v.Details.FirstOrDefault()
表达式。 EF Core 当前阶段的挑战是找到支持的可翻译等效 LINQ 构造。
在这种特殊情况下,解决方案(解决方法)是使用中间SelectMany
投影和Take(1)
。将.OrderByDescending(..)
到Page(...)
的部分替换为以下内容:
.SelectMany(
o => o.Details.Select(d => d.Delivery).Take(1).DefaultIfEmpty(),
(o, d) => new Order = o, Delivery = d )
.OrderByDescending(v => v.Delivery.ProductId)
.ThenByDescending(v => v.Delivery.Value)
.ThenByDescending(v => v.Order.CreatedAt)
.Select(v => v.Order) // restore the original projection
【讨论】:
以上是关于DetachedLazyLoadingWarning 的 Entity Framework Core 2.1 问题的主要内容,如果未能解决你的问题,请参考以下文章