C# 实体框架,移除和添加对象两次时出现InvalidOperationException
我使用的是实体框架6,首先是数据库 我有一个名为SubstanceNumber的数据库表和一个datagrid,还有一个文本框和一些用于添加新条目的gui元素,SubstanceNumber有一个外键字段 让我崩溃的场景是当我添加一个实体,删除它,再添加再删除它,这不是最常见的用例,但我觉得它揭示了我所犯的一些更大的错误C# 实体框架,移除和添加对象两次时出现InvalidOperationException,c#,entity-framework,C#,Entity Framework,我使用的是实体框架6,首先是数据库 我有一个名为SubstanceNumber的数据库表和一个datagrid,还有一个文本框和一些用于添加新条目的gui元素,SubstanceNumber有一个外键字段 让我崩溃的场景是当我添加一个实体,删除它,再添加再删除它,这不是最常见的用例,但我觉得它揭示了我所犯的一些更大的错误 My error message: System.InvalidOperationException was unhandled Message=Saving or acce
My error message: System.InvalidOperationException was unhandled
Message=Saving or accepting changes failed because more than one entity of type 'SHMD_Edit.Models.EF.SubstanceNumber' have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration.
当我添加SubstanceNumber时,我不想设置主键字段SubstanceNumber ID,因为数据库应该处理自动递增,所以在我实际输入context.SaveChanges()之前,该字段将为0
我的添加/删除命令如下所示:
public RelayCommand AddSubstanceNumberCommand
{
get
{
return new RelayCommand(
(x) =>
{
var number = new SubstanceNumber();
number.SubstanceID = Id;
number.ModifiedBy = Main.op.LoginName;
number.ModifiedDate = DateTime.Now;
number.CreatedDate = DateTime.Now;
number.Type = Converters.NumberTypeToStringConverter.translation.First(t => t.Value == SelectedNewSubstanceNumberType).Key;
number.NumberText = Validator.Normalize(NewSubstanceNumber, SelectedNewSubstanceNumberType);
var temp = NewSubstanceNumber.Replace("-", "");
number.NumberValue = Int32.Parse(temp.Substring(0, temp.Length - 1));
if (NewSubstanceNumber != null && !SubstanceNumbers.Any(sn => sn.NumberText.Replace(" ", "") == number.NumberText && sn.Type == number.Type))
SubstanceNumbers.Add(number);
NewSubstanceNumber = "";
}, param => this.CanAddSubstanceNumber);
}
}
及
我的桌子:
Column name, Data Type, Allow Nulls (is identity, identity increment=1)
SubstanceNumberID int Unchecked
SubstanceID int Unchecked
Type int Unchecked
NumberText char(16) Unchecked
NumberValue int Unchecked
CreatedDate datetime Unchecked
ModifiedDate datetime Unchecked
ModifiedBy nvarchar(16) Unchecked
RowVersion timestamp Unchecked
因此,我假设上下文和我的实体编号列表之间存在一些同步错误,但我看不到它是什么。你能指出它吗?当你删除的时候,做一些类似的事情
public virtual void Delete(T entity)
{
if (entity == null) throw new ArgumentNullException(typeof(T) + " cannot be null.");
try
{
DbEntityEntry dbEntityEntry = _DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Deleted)
{
dbEntityEntry.State = EntityState.Deleted;
}
else
{
_DbSet.Attach(entity);
_DbSet.Remove(entity);
}
}
catch (Exception ex)
{
throw;
}
}
这是来自泛型类的泛型方法,但您可以了解情况。删除之前,请检查实体的状态。如果其状态未被删除,请将状态更改为“已删除”。如果状态已删除,请附加并删除它。确保数据库中的主键设置为自动递增。这与显示实体编号以及执行上下文的时间/地点有关。SaveChanges()。介意用这些详细信息更新您的帖子吗?我在用户单击“保存”按钮时添加了表信息,I do Context.SaveChanges(),因此我的帖子场景中不涉及保存。每次我这样做时,条目状态将为!=已删除,因此我将始终将状态设置为“已删除”,从而引发异常。我也有点怀疑使用try-catch作为一种像这样的正常操作模式。删除某个内容两次不应导致任何引发的异常。
public virtual void Delete(T entity)
{
if (entity == null) throw new ArgumentNullException(typeof(T) + " cannot be null.");
try
{
DbEntityEntry dbEntityEntry = _DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Deleted)
{
dbEntityEntry.State = EntityState.Deleted;
}
else
{
_DbSet.Attach(entity);
_DbSet.Remove(entity);
}
}
catch (Exception ex)
{
throw;
}
}