我在尝试更新数据库中的记录时遇到问题。我正在C#和.NET 4.7.2中使用EF 6.2.0。
public abstract class BaseEntity { }
public abstract class Entity<T> : BaseEntity, IEntity<T>
{
//public virtual T Id { get; set; }
}
public class Order : Entity<long>
{
public long OrderID { get; set; }
...
...
...
public StatusEnum Status { get; set; }
public virtual Option Options { get; set; } = new Option();
public virtual ICollection<OrderDetail> Details { get; set; } = new List<OrderDetail>();
}
public class Option : Entity<long>
{
public long OptionID { get; set; }
...
...
...
public virtual Order Order { get; set; }
}
public class OrderDetail
{
public long OrderDetailID { get; set; }
...
...
...
public virtual Order Order { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
public DbSet<Order> Orders { get; set; }
public DbSet<Option> Options { get; set; }
...
...
...
modelBuilder.Entity<Order>()
.HasOptional(x => x.Options)
.WithRequired(x => x.Order);
}
using (var dbContext = new Context())
{
var dbItem = dbContext.Orders.FirstOrDefault(...);
if (dbItem != null)
{
dbItem.Status = StatusEnum.New;
dbItem.Details.Add(orderDetail);
dbContext.SaveChanges();
}
}
当我尝试更新时,出现以下错误
"Violation of PRIMARY KEY restriction 'PK_dbo.Option' Unable to insert a key duplicated in object 'dbo.Option'. The value of the duplicate key is (1). \ R \ nIf finished the instruction. "
我不明白为什么要尝试添加另一个具有相同ID的“选项”记录
我看到的是,在获取数据库记录时,Options带有正确的数据,但是OrderID为0,当它必须为1时(在DB中为1)
出什么问题了?谢谢!
答案 0 :(得分:0)
您没有显示代码的那部分,但是我假设您的OrderDetail
实体具有相关的导航属性Order
。现在,当添加后EF开始跟踪OrderDetail
时,默认情况下,EF也会递归地将其所有相关实体(除非已被跟踪)标记为已添加。在这种情况下,状态Options
设置为通过主实体Order
添加,因此EF尝试将其插入数据库。
解决方案可以是:
1)不设置/取消设置Order
主导航属性,而仅设置外键OrderId
;
2)调用主体实体Order
上的更新(在这种情况下,请确保以正确的状态跟踪您的Options
或未设置导航属性,否则可能会遇到同样的问题)。< / p>
出色的材料:https://msdn.microsoft.com/en-us/magazine/dn166926.aspx
编辑:显然我是盲人,因为我错过了OrderDetail
实体部分。好吧,至少我没有错过关于导航属性的猜测。 :D