将子项的更改保存到EF

时间:2013-09-14 12:58:05

标签: c# entity-framework

我建立了报告系统,用户可以选择数据并显示为报告。报告保存在三个表中(拆分实体)。但是当我尝试编辑报告并再次保存时,我收到以下错误:

  

IEntityChangeTracker的多个实例

无法引用实体对象

我的实体:

public class Report
{
    [Key]
    public int ReportId { get; set; }
    public string Title { get; set; }
    public int? DateRange { get; set; }
    public int Layout { get; set; }
    public DateTime? DateFrom { get; set; }
    public DateTime? DateTo { get; set; }
    public int OwnerId { get; set; }
    public DateTime DateCreated { get; set; }
    public bool Active { get; set; } 
    public virtual List<ReportCharts> ReportCharts { get; set; }
    public virtual List<ReportElements> ReportElements { get; set; }
}

我的EF存储库:

//Save Report to Database 
    public void Save(Report report)
    {
        assignSettingsToEntity(report);
        assignElementsToEntity(report);
        assignChartsToEntity(report);

        int found = Reports
            .Select(r => r.ReportId)
            .Where(id => id == report.ReportId)
            .SingleOrDefault();

        if (found == 0)
        {
            context.Reports.Add(report);
        }
        else
        {
            context.Entry(report).State = EntityState.Modified; // Here I get error 
        }
        context.SaveChanges();     
    }

我的DBContext

class EFDbContext : DbContext
{
    //Get Lines data from Lines table
    public DbSet<Line> Lines { get; set; }

    //Get Shifts data from Shifts table
    public DbSet<Shift> Shifts { get; set; }

    //Get list of Charts from Charts table
    public DbSet<Graph> Graphs { get; set; }

    //Get Reports data from Reports table
    public DbSet<Report> Reports { get; set; }

    // Report entity mapping
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Report>().Property(t => t.ReportId).HasColumnName("ReportId");
        modelBuilder.Entity<Report>().Property(t => t.Title).HasColumnName("Title");
        modelBuilder.Entity<Report>().Property(t => t.DateRange).HasColumnName("DateRange");
        modelBuilder.Entity<Report>().Property(t => t.Layout).HasColumnName("Layout");
        modelBuilder.Entity<Report>().Property(t => t.DateFrom).HasColumnName("DateFrom");
        modelBuilder.Entity<Report>().Property(t => t.DateTo).HasColumnName("DateTo");
        modelBuilder.Entity<Report>().Property(t => t.OwnerId).HasColumnName("OwnerId");
        modelBuilder.Entity<Report>().Property(t => t.DateCreated).HasColumnName("DateCreated");
        modelBuilder.Entity<Report>().Property(t => t.Active).HasColumnName("Active");
        modelBuilder.Entity<Report>().HasMany(t => t.ReportElements).WithRequired().HasForeignKey(c => c.ReportId).WillCascadeOnDelete(true);
        modelBuilder.Entity<Report>().HasMany(t => t.ReportCharts).WithRequired().HasForeignKey(p => p.ReportId).WillCascadeOnDelete(true);
        modelBuilder.Entity<ReportElements>().Property(c => c.ElementName).HasColumnName("ElementName");
        modelBuilder.Entity<ReportElements>().HasKey(c => new { c.ReportId, c.ElementName, c.Active });
        modelBuilder.Entity<ReportCharts>().Property(p => p.ChartId).HasColumnName("ChartId");
        modelBuilder.Entity<ReportCharts>().HasKey(c => new { c.ReportId, c.ChartId, c.Active });
    }

}

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

实体框架将每个实体附加到一个上下文,并且所有更改只能在附加到它的上下文上执行,您可能正在使用多个上下文。您应该分离并附加从不同背景获得的实体。

否则,最佳做法是不使用多个上下文实例,只在整个更改中保留一个上下文。

答案 1 :(得分:1)

听起来对象被附加到另一个上下文而没有分离。

   //Save Report to Database 
    public void Save(Report report)
    {
      using(EFDbContext context=new EFDbContext ())
      {
        assignSettingsToEntity(report);
        assignElementsToEntity(report);
        assignChartsToEntity(report);

        int found = context.Reports
            .Select(r => r.ReportId)
            .Where(id => id == report.ReportId)
            .SingleOrDefault();
        // Insert Flow
        if (found == 0)
        {
            context.Reports.Add(report);
        }
        // Update flow
        else
        {
            context.Reports.Attach(report);
            context.Entry(report).State = EntityState.Modified; 
        }
        context.SaveChanges(); 
      }         
    }