DbContext保存更改即使模型未更改也会添加数据

时间:2015-03-10 12:24:40

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

当我调用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");
}

内部异常是:

  

无法在对象&#39; dbo.Phase&#39;中插入重复的键行。具有唯一索引&#39; IX_PhaseName&#39;。重复键值为(分析)。\ r \ n   声明已被终止。

我的问题是,我不会在阶段模型中做任何事情。因此,为什么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.

1 个答案:

答案 0 :(得分:0)

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