包含未获取相关实体

问题描述 投票:0回答:1

这是我的“包含”第一次没有带回实体。不知道还缺什么

比林斯班

        public Order Order { get; set; }
        public List<BillingItem>? BillingItems { get; set; }

应用程序数据库上下文

            modelBuilder.Entity<Billing>()
                .HasOne(e => e.Order)
                .WithOne(e => e.Billing)
                .HasForeignKey<Billing>(e => e.OrderID)
                .OnDelete(DeleteBehavior.Restrict);

执行监视变量

entity-framework-core blazor entity
1个回答
0
投票

您的代码示例(未显示)做错了几件事。基本上,您正在创建一个新的 Billing 实例(很好),然后加载一个订单(好的),然后单独加载该订单的订单项目(不理想),然后将订单的 orderItems 集合设置为加载的订单项目(红色警报,不做)。从那里,您可以使用传递的订单在新的计费实例上调用一些 CreateFromOrder 方法,然后附加计费(不,不适用于插入)并调用 SaveChanges。


var billing await db.Billings
    .Include(b => b.Order)
    .ThenInclude(o => o.OrderItems)
    .SingleOrDefaultAsnc(b => b.OrderId == orderId && b.Status != Status.Deleted);

if(billing != null)
{
    billing = new Billing();
    order = await db.Orders
        .Include(o => o.OrderItems)
        .SingleAsync(o => o.Id == orderId && o.Status != Status.Deleted);
   billing.CreateFromOrder(order);
   db.Billings.Add(billing);
   await db.SaveChangesAsync();
}

我们不需要在插入后尝试重新加载账单,我们可以在开始时获取任何现有的账单。如果我们没有得到一个,创建一个新的,加载订单,急切加载订单项目,然后将其与新的账单相关联,重要的是使用

DbSet.Add()
而不是
Attach()
来确保 EF 知道这是一个新的账单.

如果我们只是想检查账单是否不存在,那么我们不需要加载它,我们可以只进行存在检查 /w

.Any()
:

var billingExists db.Billings
    .Any(b => b.OrderId == orderId && b.Status != Status.Deleted);

if(billing != null)
{
    Billing billing = new Billing();
    ...

我强烈建议在导航属性方面避免错误的一个重要更改是,无论您拥有集合导航属性(例如 Order.OrderItems),您都应该拥有可访问的设置器。例如,像

order.OrderItems = orderItems
这样的代码非常糟糕,因为更改跟踪器将有一个代理来通知何时添加/删除集合项以及当您重新分配集合时,该代理会被破坏。

代替:

public ICollection<OrderItem> OrderItems { get; set; }

集合导航属性应声明为:

public virtual ICollection<OrderItem> OrderItems { get; } = [];
// or
public virtual ICollection<OrderItem> OrderItems { get; protected set; } = new List<OrderItem>(); // for older C# versions.

任何代码都不应该在初始化后设置集合导航属性。

© www.soinside.com 2019 - 2024. All rights reserved.