繁体   English   中英

实体框架核心 - 拥有类型的修改键

[英]Entity Framework Core - Modified key on owned type

在我的数据库中保存更改时,返回带有以下消息的异常:

实体类型“Order.CustomerDeliveryDetails#CustomerDetails”的属性“OrderId”是键的一部分,因此不能修改或标记为已修改。 要使用标识外键更改现有实体的主体,首先删除依赖项并调用“SaveChanges”,然后将依赖项与新主体关联。

该数据库是使用实体框架核心实现的,采用“代码优先”方法。 Order.CustomerDeliveryDetails是实体Order的拥有类型(属于CustomerDetails类型)。 CustomerDetails没有名为OrderId的属性。 据我了解, OrderId是一个隐式键,由实体框架核心作为影子属性生成。

这些类的结构如下:

public class Order
{
    public int Id { get; set; }
    public CustomerDetails CustomerDeliveryDetails { get; set; }
}

[Owned]
public class CustomerDetails
{
    public string Street { get; set; }
}

object更新如下:

var order = await orderContext.Orders
        .Where(o => o.Id== updateOrder.Id)
        .FirstOrDefaultAsync();

order.CustomerDeliveryDetails.Street = updateOrder.CustomerDeliveryDetails.Street;
await orderContext.SaveChangesAsync();

我不明白的是,当无法在代码中直接访问OrderId时,如何修改它。

我能想到的唯一可能导致此错误的是,此更新正在 Azure 中的定时网络作业上运行。 更新通过了相关的单元测试这一事实支持了这种预感。 这可能与比赛条件有关吗?

更新:

我相当确定错误来自某种竞争条件。 定时网络作业会加载需要每 2 分钟更新一次的订单列表。 只要列表包含少于 +-100 个订单,更新就可以正常工作,但一旦此列表变长,更新就会开始失败。

如果列表过长,webjob 可能无法在 2 分钟内完成所有订单的更新。

通过依赖注入添加上下文,如下所示:

serviceProvider.AddDbContext<OrdersContext>(options => options.UseSqlServer(ctx.Configuration["ConnectionString"], sqlOptions => sqlOptions.EnableRetryOnFailure()));

我最好的猜测是上下文正在网络作业的多个调用之间共享,这导致了错误。

这归结为您的数据库关系。您是使用数据库优先还是代码优先方法? 模型是如何定义的? Order、CustomerDetails 和 CustomerDeliveryDetails 表之间的关系是什么? 请提供代码,我将能够帮助您解决问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM