【问题标题】:DbContext Save Changes adding data even if model is not changeDbContext Save Changes 添加数据,即使模型没有改变
【发布时间】:2015-03-10 12:24:40
【问题描述】:

当我调用 DbContext.SaveChanges() 时,它会将数据添加到我不想要的某个表中。

为了进一步解释这里是我的模型:

工作项

public class WorkItem 
{
    public long WorkItemID { get;set }
    /* Some properties*/

    public virtual IList<WorkItemSchedule> WorkItemSchedules {get;set;}
}

WorkItemSchedule

public class WorkItemSchedule
{
    public long WorkItemScheduleID {get;set;}
    public int PhaseID { get; set; }
    /* Some properties*/

    public virtual WorkItem WorkItem { get; set; }
    public virtual Phase Phase { get; set; }
}

阶段

public class Phase
{
    public int PhaseID {get;set;}

    [MaxLength(250)]
    [Index(IsUnique=true)]
    public string PhaseName {get;set;}
    /* Some prperies*/
}

从我的控制器保存 DbContext 更改时出现错误:

[HttpPost]
public ActionResult Generate(WorkItemScheduleViewModel viewModel)
{
    WorkItem workItem = viewModel.WorkItem;
    db.WorkItems.Add(workItem);
    db.SaveChanges();

    return RedirectToAction("Index", "WorkItem");
}

内部例外是:

无法在具有唯一索引“IX_PhaseName”的对象“dbo.Phase”中插入重复的键行。重复键值为 (Analysis)。\r\n 语句已终止。

我的问题是,我没有在 Phase 模型中做任何事情。因此,为什么 DBContext 监视器会为此更改(添加)。请帮忙。谢谢,

编辑

public class WorkItemManagerContext : DbContext
{
    public WorkItemManagerContext()
        : base("WorkItemManagerConnString")
    {
    }

    public DbSet<Phase> Phases { get; set; }
    public DbSet<WorkItem> WorkItems { get; set; }
    public DbSet<WorkItemSchedule> WorkItemSchedules { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

这是我得到的内部异常:

Attaching an entity of type 'WorkItemManager.Models.WorkItemSchedule' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

【问题讨论】:

  • WorkItemScheduleViewModel 长什么样子?
  • 这只是一个收集workitemschedule的视图模型,我认为这与错误无关,因为我没有对dbcontext进行任何更改。

标签: c# asp.net-mvc entity-framework


【解决方案1】:

DbSet.Add() 方法将整个对象图(实体及其所有相关实体)标记为“已添加”,这将始终导致插入。我建议始终使用DbSet.Attach() 方法,因为它不对对象图的状态做出任何假设,并希望您使用DbContext.Entry(entityVariable).State 手动设置每个实体的状态。

如果你绝对确定整个对象图是新的并且应该触发插入,你可以使用DbSet.Add(),但我认为最好避免它。

以下代码使 DbContext 开始跟踪实体并将 workItem 标记为已添加,但不会导致 WorkItemSchedules 集合的插入。

[HttpPost]
public ActionResult Generate(WorkItemScheduleViewModel viewModel)
{
    WorkItem workItem = viewModel.WorkItem;
    db.WorkItems.Attach(workItem);
    db.Entry(workItem).State = EntityState.Added;
    db.SaveChanges();

    return RedirectToAction("Index", "WorkItem");
}

https://msdn.microsoft.com/en-us/data/jj592676

【讨论】:

  • WorkItemManagerContext 不包含“附加”的定义:(我将更新我的问题,以便您可以看到。
  • 附加在 DbSet 上。我更新了我的答案。很抱歉造成混乱。
  • 谢谢!!我认为这是我的问题的正确答案。但是我现在有另一个问题,默认情况下,WorkItem.WorkItemID 设置为'0',我怎样才能正确创建一个有效并递增到最后的WorkItemID?再次感谢。
  • 调用db.SaveChanges() 后,workItem.WorkItemID 中应该包含数据库生成的值。
  • 我的意思是,我从 db.WorkItems.Attach(workItem) 得到 InvalidOperationException
猜你喜欢
  • 2018-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-25
  • 2021-03-04
  • 2022-08-18
相关资源
最近更新 更多