英文:
EF Core 7.0 Error: "Add the entity seed to 'X' and specify the foreign key values" when already specified
问题
我在种植单向关系方面遇到了问题。种植看起来如下:
- 用户 1 --> * 帖子
我在配置上收到了这个错误:
未处理的异常。System.InvalidOperationException:不能添加实体类型为 'User' 的种子实体,因为它具有设置的导航 'Posts'。要种子关系,请将实体种子添加到 'Post' 并指定外键值 {'UserId'}。
对我来说,这个错误毫无意义,因为我已经明确指定了外键值 Post.UserId...
任何帮助都将不胜感激!
这是我的配置:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.User>()
.HasMany(user => user.Posts)
.WithOne()
.HasForeignKey(post => post.UserId)
.IsRequired(false);
Models.User user = new() { Id = 1, Username = "user" };
Models.Post post = new() { Id = 1, Body = "Hello from the other side", UserId = 1 };
user.Posts.Add(post);
modelBuilder.Entity<Models.User>().HasData(user);
modelBuilder.Entity<Models.Post>().HasData(post);
}
这是我的类定义:
public abstract class Base
{
[Key]
public int Id { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
public DateTime? UpdateAt { get; set; }
}
public class Post : Base
{
[Required] public string Body { get; set; }
public int? UserId { get; set; }
}
public class User : Base
{
[Required] public string Username { get; set; }
[ForeignKey(nameof(Post.UserId))] public ICollection<Post> Posts { get; set; } = new List<Post>();
}
希望这对你有所帮助。
英文:
I am having trouble seeding unidirectional relationships. The seeding looks as follows:
- User 1-->* Post
I'm receive this error on configuration
> Unhandled exception. System.InvalidOperationException: The seed entity for entity type 'User' with the key value 'Id:1' cannot be added because it has the navigation 'Posts' set. To seed relationships, add the entity seed to 'Post' and specify the foreign key values {'UserId'}.
This error makes no sense to me, as I am already explicitly specifying the foreign key value Post.UserId...
Any help is much appreciated!
Here is my configuration
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.User>()
.HasMany(user => user.Posts)
.WithOne()
.HasForeignKey(post => post.UserId)
.IsRequired(false);
Models.User user = new() { Id = 1, Username = "user" };
Models.Post post = new() { Id = 1, Body = "Hello from the other side", UserId = 1 };
user.Posts.Add(post);
modelBuilder.Entity<Models.User>().HasData(user);
modelBuilder.Entity<Models.Post>().HasData(post);
}
And here are my class definitions
public abstract class Base
{
[Key]
public int Id { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
public DateTime? UpdateAt { get; set; }
}
public class Post : Base
{
[Required] public string Body { get; set; }
public int? UserId { get; set; }
}
public class User : Base
{
[Required] public string Username { get; set; }
[ForeignKey(nameof(Post.UserId))] public ICollection<Post> Posts { get; set; } = new List<Post>();
}
答案1
得分: 0
我发现了我的实现中的错误,如果有人遇到相同的问题。
在创建阶段,您不应该填充虚拟集合,即在这种情况下的 User.Posts,因为外键是 EF 用来在稍后填充集合的。基本上删除 user.Posts.Add(post);
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.User>()
.HasMany(user => user.Posts)
.WithOne()
.HasForeignKey(post => post.UserId)
.IsRequired(false);
Models.User user = new() { Id = 1, Username = "user" };
Models.Post post = new() { Id = 1, Body = "Hello from the other side", UserId = 1 };
modelBuilder.Entity<Models.User>().HasData(user);
modelBuilder.Entity<Models.Post>().HasData(post);
}
此外,EF 在幕后实现了延迟加载,因此在从数据库获取数据时,您必须包括虚拟集合以填充它们。这在 repositories/User.cs 中体现:
public static Models.User? Get(string username)
{
using Contexts.Main context = new();
return context.Users.Include(user => user.Posts).SingleOrDefault(user => user.Username == username);
}
英文:
I found the error in my implementation for anyone experiencing the same.
In the creation phase, you are not supposed to populate virtual collections, in this case User.Posts, as the foreign key is what EF uses to populate the collections later on. Basicailly remove user.Posts.Add(post);
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.User>()
.HasMany(user => user.Posts)
.WithOne()
.HasForeignKey(post => post.UserId)
.IsRequired(false);
Models.User user = new() { Id = 1, Username = "user" };
Models.Post post = new() { Id = 1, Body = "Hello from the other side", UserId = 1 };
modelBuilder.Entity<Models.User>().HasData(user);
modelBuilder.Entity<Models.Post>().HasData(post);
}
On top of that, EF implements lazy loading behind the scenes, so when fetching data from the DB, you must include your virtual collections to populate them. This is in repositories/User.cs:
public static Models.User? Get(string username)
{
using Contexts.Main context = new();
return context.Users.Include(user => user.Posts).SingleOrDefault(user => user.Username == username);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论