c# - Entity Framework Core 2.1 存在 DetachedLazyLoadingWarning 问题

标签 c# entity-framework ef-code-first entity-framework-core code-first

我收到 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/

相关文章:

entity-framework - LinqPad + EF 4.1 + SQL Server CE

c# - VS2017 具有新的 getter/setter 语法 : How to write multiple lines in the setter?/

c# - 带有 Oracle 表/ View 的 Entity Framework 5 不存在不一致?

c# - 我可以更改 Entity Framework 4.3 代码优先中的默认架构名称吗?

c# - 在代码中设置 Entity Framework 的凭据,不使用 Integrated Security 并且仅将用户 ID 存储在配置文件中

java - JPA 获取连接实体返回递归获取循环

ef-code-first - EF Code First 使用非主键创建一对多关系

c# - 以编程方式使用管理员帐户向注册表中的其他用户添加 key

c# - 使用 EventHandler 更新主线程中的控件

c# - LoadState 和 navigationHelper_LoadState 之间的区别