INSERT语句与FOREIGN KEY约束“FK_PostTag_Tag_TagId”冲突

时间:2016-03-03 11:37:12

标签: entity-framework entity-framework-core

我正在使用 Entity Framework 7 RC1 ,我有实体:

__new__

这些实体的模型配置如下:

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

有谁知道这个错误的原因?

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。这是我提出的解决方案。 This这个问题给了我很多帮助。

首先,如果缺少public DbSet<Tag> Tags {get; set;}课程,请添加Context

然后按如下方式修改帖子创建

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对象之前,明确地将tagcontext.Posts添加到context.TagsPostTag允许EF在写入时正确管理ID基础数据库。

为了完整起见,在解决了多对多关系管理的这一部分后,我目前正在与CascadeDelete实体框架核心(EF7)进行斗争,但这是一个不同的故事。

答案 1 :(得分:0)

我想说你不需要在EF CodeFirst中显式声明你的外键,框架会为你处理它。因此,从PostTag类中删除这些属性

public Int32 PostId { get; set; }
public Int32 TagId { get; set; }

然后从配置中删除这两行,然后再次尝试保存。您可能需要在保存之前更新数据库模型。

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