我正在自学实体框架核心。实际上,我对整个.net世界来说还比较陌生。
我有以下类似的类(对伪代码表示歉意,实际代码太长了,无法在此处粘贴)。
Account
{
User UserInfo {get;set;}
}
User
{
string Email {get;set;}
}
Admin:Account
{
// some properties
}
我正在尝试使用EF代码优先模式生成数据库表。在上面的类中,我有一个种子例程,如下所示:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>().HasData(
new Admin
{
UserInfo = new User {Email = "abc@xyz.com"}
});
}
使用上述方法,当我尝试创建初始迁移时,出现以下错误:
不能添加实体类型“ Account”的种子实体,因为提供的值是派生类型“ Admin”的。将派生的种子实体添加到相应的实体类型。
因此,我更改了如下代码(用Admin替换了帐户):
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Admin>().HasData(
new Admin
{
UserInfo = new User {Email = "abc@xyz.com"}
});
}
现在我收到此错误(不确定UserInfoEmail
的来源):
不能添加实体类型'Admin'的种子实体,因为它已设置了导航'UserInfo'。要播种关系,您需要将相关实体种子添加到'User'并指定外键值{'UserInfoEmail'}。考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'查看所涉及的属性值。
使用代码优先模式时,我无所适从地理解了处理关系的整个概念。有人可以帮我了解上述错误的含义,以及在使用EF代码优先模式时如何处理关系(特别是组成和继承)。
答案 0 :(得分:0)
第二次尝试已经结束,但是您犯了一个错误:
modelBuilder.Entity<Admin>().HasData(
new Admin
{
UserInfo = new User {Email = "abc@xyz.com"}
});
看,这里您将UserInfo
设置为new User
。您的错误意味着您无法在尝试添加User
实体时添加Admin
实体。而是先添加User
,然后再从Admin
实体中引用它(看起来Email
是您在User
实体中的主键):
modelBuilder.Entity<User>().HasData(
new User
{
Email = "abc@xyz.com"
});
modelBuilder.Entity<Admin>().HasData(
new Admin
{
UserInfoId = "abc@xyz.com"
});
如果您在UserInfoId
类中没有Account
,只需添加它即可:
class Account
{
User UserInfo { get; set; }
string UserInfoId { get; set; }
}