英文:
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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论