我收到 DetachedLazyLoadingWarning 异常:
Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning: An attempt was made to lazy-load navigation property 'Product' on detached entity of type 'DeliveryProxy'. Lazy-loading is not supported for detached entities or entities that are loaded with 'AsNoTracking()'.'. This exception can be suppressed or logged by passing event ID 'CoreEventId.DetachedLazyLoadingWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.
尝试使用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。如何改进查询以仅使用一个查询从数据库获取日期(抑制警告没有帮助)?
最佳答案
您还应该看到很多 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
关于c# - Entity Framework Core 2.1 存在 DetachedLazyLoadingWarning 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53241864/