INSERTステートメントがFOREIGN KEY制約 "FK_PostTag_Tag_TagId"と競合しました。

entity-framework entity-framework-core

質問

私は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();

明示的に両方の追加posttagcontext.Postscontext.Tags作成する前にPostTagオブジェクトは、基礎となるDBへの書き込み中にEFが正しくのIDを管理することができます。

完全性のために、この多対多リレーションシップマネジメントのこの部分を解決した後、私は現在、CascadeDelete Entity Frameworkコア(EF7)に苦労していますが、これは別の話です。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ