私の問題を説明するために、書籍のコレクションを持つデータ モデルがあり、それぞれに 1 つ以上のドラフトと「現在の」ドラフトがあるとします。モデルを次のようにしたいと思います。
class Book
{
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<Draft> Drafts { get; set; }
public virtual Draft CurrentDraft { get; set; }
}
class Draft
{
public int Id { get; set; }
public virtual int BookId { get; set; }
public virtual Book Book { get; set; }
public string Description { get; set; }
}
次のような DbContext があります。
class TestDbContext : DbContext
{
public DbSet<Book> Books { get; set; }
public DbSet<Draft> Drafts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
base.OnModelCreating(modelBuilder);
}
}
...そして、次のような単純なプログラム:
static void Main(string[] args)
{
Database.SetInitializer<TestDbContext>(new DropCreateDatabaseAlways<TestDbContext>());
using (var db = new TestDbContext())
{
var book = new Book() { Title = "War and Peace", Drafts = new List<Draft>() };
var draft1 = new Draft() { Book = book, Description = "First Draft" };
book.Drafts.Add(draft1);
var draft2 = new Draft() { Book = book, Description = "Second Draft" };
book.Drafts.Add(draft2);
book.CurrentDraft = draft2;
db.Books.Add(book);
db.SaveChanges();
foreach (var b in db.Books)
{
Console.WriteLine("Book {0}: {1}", b.Id, b.Title);
foreach (var d in book.Drafts)
Console.WriteLine("\tDraft ID {0}: {1} from Book ID {2}", d.Id, d.Description, d.BookId);
Console.WriteLine("Current draft has ID {0}", b.CurrentDraft.Id);
}
Console.ReadKey();
}
}
DB が EF によって作成されると、次のようになります。
[私は追加の Book_Id 列に熱狂的ではありませんが、それが機能するなら我慢できます。]
悲しいことに、テスト プログラムを実行すると、SaveChanges
呼び出しで失敗し、例外が発生します。
リレーションシップの外部キー プロパティを公開しないエンティティの保存中にエラーが発生しました。1 つのエンティティを例外のソースとして識別できないため、EntityEntries プロパティは null を返します。保存中の例外の処理は、エンティティ タイプで外部キー プロパティを公開することで簡単に行うことができます。詳細については、InnerException を参照してください。
OnModelCreating で流暢な API をいじってみましたが、そのように構成しようとすると、Books と Drafts の間に 2 つの FK 関係があるという事実によって混乱します。私は流暢なもの (または一般的には EF) に精通していないため、適切に行う方法を知ることができません。
これは最初にEFコードでも可能ですか?