我收到DetachedLazyLoadingWarning异常:
为警告“ Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning”而生成的错误:尝试对类型为“ DeliveryProxy”的分离实体延迟加载导航属性“产品”。分离的实体或使用'AsNoTracking()'加载的实体不支持延迟加载。通过将事件ID'CoreEventId.DetachedLazyLoadingWarning'传递到'DbContext.OnConfiguring'或'AddDbContext'中的'ConfigureWarnings'方法,可以抑制或记录该异常。
尝试使用实体框架代码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 Framework6。如何仅使用一个查询来改进查询以从数据库中获取日期(抑制警告无济于事)?
答案 0 :(得分:2)
您还应该看到很多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