【发布时间】:2020-06-03 17:06:00
【问题描述】:
我有一个这样定义的聚合:
public class Product {
public int LocalId { get; private set; }
public Something Something { get; private set; }
public ICollection<Price> Prices { get; private set; }
}
public class Something {
public string Name { get; set; }
}
public class Price {
public int Type { get; set; }
public decimal Value { get; set; }
}
还有这样定义的架构:
private void DefineProduct(ModelBuilder builder) =>
builder
.Entity<Product>(builder =>
{
builder.HasKey(p => p.LocalId);
builder
.OwnsOne(p => p.Something, smth =>
{
smth.ToTable("somethings");
})
.OwnsMany(p => p.Prices, pp =>
{
pp.ToTable("prices");
});
});
当请求更改价格时,我会这样做(为简洁起见,在产品方法中不包括在内):
Prices.First(p => p.Type == type).Value = newValue;
然后我尝试像这样保存产品:
public async Task UpdateProperties(Product product, IEnumerable<object> props)
{
_context.Attach(product);
_context.Update(product);
foreach (var prop in props)
{
_context.Update(prop);
}
try
{
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
Console.WriteLine("Who the hell allowed such a bug to go into a production release?");
}
}
现在我应该提到该产品来自未跟踪结果的初始查询(通过AsNoTracking() 调用),这就是我在方法主体的第一行调用Attach 方法的原因。问题是我在使用catch 语句时出现异常消息:
数据库操作预计会影响 1 行,但实际上会影响 0 行。数据可能已被修改或删除,因为实体 加载。见http://go.microsoft.com/fwlink/?LinkId=527962 有关理解和处理乐观并发的信息 例外。”}
问题是我不会在其他任何地方更新相同的产品,这是唯一接触它的地方。我也使用AsNoTracking 作为默认值。如果我用_context.Update(prop); 注释掉该行,则不会引发异常,但价格不会更新。此外,如果我不更新该价格集合而是更新Something 属性,那么一切顺利。什么。这。地狱。
【问题讨论】:
-
嗨,不完全确定:
_context.Attach(product).State = EntityState.Modified;向 EF 发出信号,表示它应该重新跟踪它。 (对于 EF 非核心:_context.Entry(product).State = EntityState.Modified;) -
我遇到了同样的错误:(
标签: c# entity-framework-core owned-types