[英]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.