私はEntity Framework 7 RC1を使用しており、エンティティを持っています:
public class Post {
public Int32 Id { get; set; }
public String Title { get; set; }
public virtual IList<PostTag> PostsTags { get; set; }
}
public class Tag {
public Int32 Id { get; set; }
public String Name { get; set; }
public virtual IList<PostTag> PostsTags { get; set; }
}
public class PostTag {
public Int32 PostId { get; set; }
public Int32 TagId { get; set; }
public virtual Post Post { get; set; }
public virtual Tag Tag { get; set; }
}
これらのエンティティのモデル構成は次のとおりです。
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
builder.Entity<Post>(b => {
b.ToTable("Posts");
b.HasKey(x => x.Id);
b.Property(x => x.Id).UseSqlServerIdentityColumn();
b.Property(x => x.Title).IsRequired().HasMaxLength(100);
});
builder.Entity<Tag>(b => {
b.ToTable("Tags");
b.HasKey(x => x.Id);
b.Property(x => x.Id).UseSqlServerIdentityColumn();
b.Property(x => x.Name).IsRequired().HasMaxLength(100);
});
builder.Entity<PostTag>(b => {
b.ToTable("PostsTags");
b.HasKey(x => new { x.PostId, x.TagId });
b.HasOne(x => x.Post).WithMany(x => x.PostsTags).HasForeignKey(x => x.PostId);
b.HasOne(x => x.Tag).WithMany(x => x.PostsTags).HasForeignKey(x => x.TagId);
});
}
私は移行とデータベースを作成しました。それから私は投稿を作成しようとしました:
Context context = new Context();
Post post = new Post {
PostsTags = new List<PostTag> {
new PostTag {
Tag = new Tag { Name = "Tag name" }
}
},
Title = "Post title"
};
context.Posts.Add(post);
await _context.SaveChangesAsync();
そして保存すると、次のエラーが発生します。
An error occurred while updating the entries.
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_PostTag_Tag_TagId".
The conflict occurred in database "TestDb", table "dbo.Tags", column 'Id'.
The statement has been terminated.
誰もがこのエラーの理由を知っていますか?
私も同じ問題がありました。ここに私が思いついた解決策があります。 この SOの質問は私を助けてくれました。
まず、 public DbSet<Tag> Tags {get; set;}
追加しpublic DbSet<Tag> Tags {get; set;}
あなたがContext
クラスを見つけたらそれをpublic DbSet<Tag> Tags {get; set;}
。
次に、投稿作成を次のように変更します
Context context = new Context();
var tmpTag = new Tag { Name = "Tag name" } //add the tag to the context
context.Tags.Add(tmpTag);
Post post = new Post {
PostsTags = new List<PostTag>(), // initialize the PostTag list
Title = "Post title"
};
context.Posts.Add(post);
var postTag = new PostTag() {Post = post, Tag = tag}; // explicitly initialize the PostTag AFTER addig both Post and Tag to context
post.PostTags.Add(postTag); // add PostTag to Post
await _context.SaveChangesAsync();
明示的に両方の追加post
やtag
にcontext.Posts
とcontext.Tags
作成する前にPostTag
オブジェクトは、基礎となるDBへの書き込み中にEFが正しくのIDを管理することができます。
完全性のために、この多対多リレーションシップマネジメントのこの部分を解決した後、私は現在、CascadeDelete Entity Frameworkコア(EF7)に苦労していますが、これは別の話です。