2013-09-14 3 views
0

У меня есть система отчетности, в которой пользователь может выбирать данные и отображать их как отчет. Отчет сохраняется в трех таблицах (разделенный объект). Но когда я пытаюсь изменить отчет и сохранить снова я получаю следующее сообщение об ошибке:Сохранение изменений в EF с детьми

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

Мой Entity:

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 }); 
    } 

} 

Спасибо за любую помощь.

ответ

1

Entity Framework прикрепляет каждую сущность к одному контексту, и все изменения могут выполняться только в контексте, к которому он привязан, вы, вероятно, используете несколько контекстов. Вы должны отсоединить и прикрепить сущность, полученную из другого контекста.

В противном случае наилучшей практикой является не использование нескольких экземпляров контекста, а сохранение только одного контекста во всех ваших изменениях.

+0

Я использую только один контекст, но несколько dbsets в контексте, это то, что вы имеете в виду? Я редактировал свой вопрос, чтобы добавить класс DbContext. – Whistler

+0

Где находится метод сохранения? и что добавляет методы? вы создаете новый контекст, в контексте я имею в виду экземпляр контекста, у вас может быть один класс, но если у вас несколько экземпляров, это проблема. –

+0

Решено: я ошибся, поскольку я загружал объект для редактирования и назначал его переменной сеанса, которая, я считаю, теперь была множественным экземпляром, который вы упомянули. Большое спасибо за вашу помощь – Whistler

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(); 
     }   
    } 
Смежные вопросы