2016-09-03 8 views
0

に更新されない:子コレクションは、ネストされた1-あまりにも多くの関係では、次の単純化されたモデルを考えてみましょうEntityFrameworkCore

public class Report 
{ 
    public Guid ReportId { get; set; } 
    public string Name { get; set; } 
    public List<Schedule> Schedules { get; set; } 
} 

public class Schedule 
{ 
    public Guid ScheduleId { get; set; } 
    public string Title { get; set; } 
    public List<Description> Descriptions { get; set;} 

    // FK 
    public Guid ReportId { get; set; } 
    public Report Report { get; set; } 
} 

public class Description 
{ 
    public Guid DescriptionId { get; set; } 
    public string Content { get; set; } 

    // FK 
    public Guid ScheduleId { get; set; } 
    public Schedule Schedule { get; set; } 
} 

public class DataContext : DbContext 
{ 
    public DbSet<Report> Reports { get; set; } 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
    { 
     optionsBuilder.UseSqlite("Filename=mydbname.db"); 
    } 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Report>() 
      .HasMany(report => report.Schedules) 
      .WithOne(schedule => schedule.Report); 
     modelBuilder.Entity<Schedule>() 
      .HasOne(schedule => schedule.Report) 
      .WithMany(report => report.Schedules) 
      .OnDelete(DeleteBehavior.Cascade); 
     modelBuilder.Entity<Description>() 
      .HasOne(description => description.Schedule) 
      .WithMany(schedule => schedule.Descriptions) 
      .OnDelete(DeleteBehavior.Cascade); 
    } 
} 

予想通り、各項目が各テーブルに挿入された作品の追加:

Description description = new Description(); 
description.DescriptionId = Guid.NewGuid(); 
description.Content = "my content"; 

Schedule schedule = new Schedule(); 
schedule.ScheduleId = Guid.NewGuid(); 
schedule.Title = "my schedule"; 
schedule.Descriptions = new List<Description>(); 
schedule.Descriptions.Add(description); 

Report report = new Report; 
report.ReportId = Guid.NewGuid(); 
report.Name = "my report"; 
report.Schedules = new List<Schedule>(); 
report.Schedules.Add(schedule); 

using(var db = new DataContext()) 
{ 
    db.Reports.Add(report); 
    db.SaveChanges(); 
} 

をエンティティの削除も正常に機能しますが、すべてのアイテムは各テーブルで削除されます。

using(var db = new DataContext()) 
{ 
    db.Reports.Remove(report); 
    db.SaveChanges(); 
} 

これまでの更新エンティティは、コレクションに新しいアイテムを追加するときではなく、既存のアイテムのコンテンツを変更する場合にのみ機能します。例:

// this works 
report.Name = "updated report"; 
report.Schedules.ElementAt(0).Descriptions.ElementAt(0).Content = "updated content"; 
using(var db = new DataContext()) 
{ 
    db.Reports.Update(report); 
    db.SaveChanges(); 
} 

// this throws DbUpdateConcurrencyException because no rows are affected. 
Description newDescription = new Description(); 
newDescription.DescriptionId = Guid.NewGuid(); 
newDescription.Content = "new content"; 

Schedule newSchedule = new Schedule(); 
newSchedule.ScheduleId = Guid.NewGuid(); 
newSchedule.Title = "new schedule"; 
newSchedule.Descriptions = new List<Description>(); 
newSchedule.Descriptions.Add(newDescription); 

report.Schedules.Add(newSchedule); 
using(var db = new DataContext()) 
{ 
    db.Reports.Update(report); 
    db.SaveChanges(); 
} 

コレクションにアイテムを正しく追加して後で更新するにはどうすればよいですか?私のテーブルデザインは理にかなっていますか?が

Sunteen - MSFT postが示すのと同じように、私のコードで間違って何もなさそうです

List<Report> Reports; 
using (var db = new DataContext()) 
    Reports = db.Reports 
        .Include(report => report.Schedules) 
         .ThenInclude(schedule => schedule.Descriptions) 
        .ToList() 

EDIT:これは私がレポートオブジェクトを取得する方法です。私の場合、問題を引き起こしていることが分かりました。私は意図的に各エンティティの主キーID(Guid.NewGuid())を生成するはずです。判明したように、IDは自動的に生成され、問題は解決されます。 Sunteen - MSFTありがとうございます。

+0

レポートオブジェクトをどのように取得していますか? –

+0

選択された回答の編集が役に立ちます:http://stackoverflow.com/questions/32543448/update-of-navigation-property-in-ef7-does-not-get-saved –

+0

@SegmentationFault私は編集しました。あなたがレポートをフェッチする方法を示す投稿 –

答えて

1

問題を再現できません。私が書いた唯一のコードは、コードスニペットに表示されていないreportオブジェクトを取得することです。更新しようとしているreportオブジェクトがテーブルに存在することを確認してください。次のように私はちょうど私があなたのコードとデモを作成し、それがうまく働いていた、と私はgithubのにdemoをアップロードし、

using (var db = new DataContext()) 
{ 
    List<Report> Reports; 
    Reports = db.Reports.Include(report1 => report1.Schedules) 
         .ThenInclude(schedule => schedule.Descriptions) 
        .ToList(); 
    var report = Reports[0]; 

    Description newDescription = new Description(); 
    newDescription.DescriptionId = Guid.NewGuid(); 
    newDescription.Content = "new content"; 

    Schedule newSchedule = new Schedule(); 
    newSchedule.ScheduleId = Guid.NewGuid(); 
    newSchedule.Title = "new schedule"; 
    newSchedule.Descriptions = new List<Description>(); 
    newSchedule.Descriptions.Add(newDescription); 
    report.Schedules.Add(newSchedule); 
    db.Reports.Update(report); 
    db.SaveChanges(); 
} 

Report表から最初のレコードを持って、その後、更新、コードは、テストのためにダウンロードすることができますあなたのプロジェクトと比較して違いを見つけることができます。比較の相違で解決できない場合は、このデモで問題を再現して解決し直すことができます。

+0

ありがとう、それはあなたのとても素敵でした。私は現在大学のもので忙しく、利用可能な場合は自分のコードと私のコードを比較し、その結果を返すでしょう。再度、感謝します! –

+0

あなたのコードではまさにそれが期待どおりに機能するので、私の間違いがあるはずです。それを指摘してくれてありがとう! –

関連する問題