【问题标题】:Entity framework fails to save if multiple records under same list has `EntityState.Added`如果同一列表下的多个记录具有 `EntityState.Added`,则实体框架无法保存
【发布时间】:2017-11-22 16:46:48
【问题描述】:

我有以下情况,我必须做一些事前检查,并据此决定grade 对象是否将使用修改后的子/子对象或新的子/子对象进行更新。

Students 列表中只有一个studentstudentIdentity = 0 时,以下情况非常有效,但是如果列表中有多个Students(带有studentIdentity = 0)应该添加和设置EntityState.Added 然后它无法将上下文保存回数据库。

上下文类:

public virtual void SetAdded(object entity)
{
    Entry(entity).State = EntityState.Added;
}

public virtual void SetModified(object entity)
{
    Entry(entity).State = EntityState.Modified;
}

存储库类:

if (grade.Teachers.IsNotNull() && grade.Teachers.Any())
{
     grade.Teachers.ForEach(i => SchoolContext.SetModified(i));
}

//Add or update Students
if (grade.Students.IsNotNull() && grade.Students.Any())
{
     grade.Students.ForEach(s =>
     {
          if (s.StudentIdentity == 0) //Works well if only one with Identity = 0 , if goes thru this multiple times, fails
          {
                SchoolContext.SetAdded(s);
          }
          else
          {
                SchoolContext.SetModified(s);
          }
     });
}

results = await StudentContext.SaveChangesAsync().ConfigureAwait(false);

得到以下异常:

存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体后,实体可能已被修改或删除。

在处理多个新添加时需要注意什么?

【问题讨论】:

  • 什么是SetAddedSetModified?分享该代码。

标签: c# .net sql-server entity-framework entity-framework-6


【解决方案1】:

Entry(entity).State = EntityState.Added;

那行不正确。您需要将实体添加DbContext 上的正确DbSet 或使用DbContext 上的通用DbSet<T>(属性名为Set)。 DbSet<T> 上的方法是 Add

例如,这可以工作:

public virtual void SetAdded<T>(T entity) where T : class
{
    this.Set<T>().Add(entity);
}

关于您修改的实体。如果DbContext 正在跟踪它们,则无需将状态设置为已修改。如果DbContext 没有跟踪它们(如果它们是在DbContext 之外创建的,则可能发生这种情况),那么您需要将它们附加到DbContext。此时,您可以将状态设置为已修改以更新实体上的所有属性,或者您可以对实体进行更改之后附加到该实体被跟踪的点,并且仅对实体的修改将被更新。

如果您想附加断开连接的实体,您可以这样做:

public virtual void SetModified<T>(T entity) where T : class
{
    this.Set<T>().Attach(entity);
    Entry(entity).State = EntityState.Modified; 
}

最后,我建议在您的 DbContext 类型上指定特定的 DbSet&lt;T&gt; 属性并直接使用这些属性。然后在这些属性上调用 Add 或 Attach 等。

【讨论】:

  • 这个解释很有帮助!!但是仍然无法理解,this.Set&lt;T&gt;().Add(entity);Entry(entity).State = EntittyState.Add 的工作方式有何不同?
  • @AviKenjale - .Add 将实体和任何关联的新关系添加到状态为 Add 的 DbContext 中,实体将由 DbContext 跟踪并确保在您调用时创建它们SaveChangesEntry(entity) 应该还存在于您的 DbContext 中,如果在您完成此步骤之前它是新的,那么此时更改状态无效。
  • 我相信 SetModified 方法必须修改,并且应该将 Entry(entity).State = EntityState.Modified; 作为附加实体并将状态设置为修改后使其可以更新。仅附加并没有更多作用。
【解决方案2】:

你试过了吗:SchoolContext.Students.Add(s);

我假设StudentsDbSet 在这种情况下SchoolContext 的属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    相关资源
    最近更新 更多