我使用实体框架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.
有谁知道此错误的原因?
我想说的是,你不需要在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);
我也有同样的问题。这是我想出的解决方案。这个SO问题对我帮助很大。
首先,添加一个公共数据库集
然后修改帖子创建,如下所示
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
和标记
显式添加到上下文。在尝试创建
上下文和PostTag
对象之前发布context。这使EF能够在向底层DB写入时正确管理ID。
为了完整起见,在解决了多对多关系管理的这一部分之后,我目前正在努力使用CascadeDelete Entity Framework Core(EF7),但那是另一回事。