如何解决EF Core 模型种子数据在键名中强加复数形式
class Post {
ICollection<Tag> Tags {get; set;} = new List<Tag>();
}
class Tag {
ICollection<Post> Posts {get; set;} = new List<Post>();
}
Tag
和 Post
类具有相应的 Tag
和 Post
表,带有 TagId
和 PostId
主键(注意单数 命名约定)
在配置我的 Post
的构建器时,我说
builder
.HasMany(p => p.Tags)
.WithMany(p => p.Posts)
.UsingEntity(j => j.HasData(new { PostId = 1,TagId = 1 }));
当我添加 try 到 add-migration Initial
时,阻塞错误会中断迁移创建:
实体类型 'PostTag (Dictionary
有人能解释一下这条消息背后隐藏了什么吗?
我看到它通过复数(PostsId
vs PostId
),但我不想在外键上使用复数,有没有办法使用 PostId
而不是 PostsId
?
.UsingEntity(j => j.HasData(new { PostsId = 1,TagsId = 1 }));
此外,它还会创建以下迁移:
migrationBuilder.CreateTable(
name: "PostTag (Dictionary<string,object>)",columns: table => new
{
PostsId = table.Column<int>(type: "int",nullable: false),TagsId = table.Column<int>(type: "int",nullable: false)
},constraints: table =>
{
table.PrimaryKey("PK_PostTag (Dictionary<string,x => new { x.PostsId,x.TagsId });
table.ForeignKey(
name: "FK_PostTag (Dictionary<string,object>)_Post_PostsId",column: x => x.PostsId,principalTable: "Post",principalColumn: "PostId",onDelete: referentialAction.Cascade);
表名“PostTag (Dictionary
使用这些约定的逻辑是什么?怎样做才能拥有正常的 PostTag
表名?
解决方法
正如错误消息中所写,如果您想使用多对多,您应该在两个表中都有主键:
public class Post
{
[Key]
public int PostId { get; set; }
public ICollection<Tag> Tags { get; set; }
}
public class Tag
{
[Key]
public int TagId { get; set; }
public ICollection<Post> Posts { get; set; }
}
和数据库上下文:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var posts = new[]
{
new Post{PostId=1},new Post{PostId=2},new Post{PostId=3}
};
var tags = new[]
{
new Tag{TagId=1},new Tag{TagId=2}
};
modelBuilder.Entity<Tag>().HasData(tags);
modelBuilder.Entity<Post>().HasData(posts);
modelBuilder.Entity<Post>()
.HasMany(p => p.Tags)
.WithMany(p => p.Posts)
.UsingEntity(j => j.HasData(new { PostsPostId = 1,TagsTagId = 1 }));
}
,
当 EF 为您生成某些内容时,它遵循其特定的命名约定。 PostTag
是 EF 生成的连接表,用于维护多对多关系,您不应该知道它的存在以及 EF 如何管理它。
如果您确实想知道该表并希望它的列以您的方式命名,那么您必须创建连接实体,按照您希望的方式命名属性并对其进行显式配置。
加入实体-
public class PostTag
{
public int PostId { get; set; }
public int TagId { get; set; }
public Post Post { get; set; }
public Tag Tag { get; set; }
}
配置以及种子 -
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>(e =>
{
e.ToTable("Post").HasData(new Post { Id = 1,Title = "EF Deep Dive" });
e.HasMany(p => p.Tags)
.WithMany(p => p.Posts)
.UsingEntity<PostTag>(
link => link.HasOne(p => p.Tag).WithMany().HasForeignKey(p => p.TagId),link => link.HasOne(p => p.Post).WithMany().HasForeignKey(p => p.PostId))
.HasKey(p => new { p.PostId,p.TagId });
});
modelBuilder.Entity<Tag>(e =>
{
e.ToTable("Tag").HasData(new Tag { Id = 1,Name = "EF" },new Tag { Id = 2,Name = ".NET" });
});
modelBuilder.Entity<PostTag>().HasData(new { PostId = 1,TagId = 1 });
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。