我的应用程序中有一个名为Person的实体。从Person继承的用户有两种类型:Student和Professor。
每个人都有一个设置属性:
public abstract class Person
{
public Guid UserId { get; set; }
public string Name { get; set; }
public PersonSettings Settings { get; set; }
}
public class Student : Person
{
}
public class Professor : Person
{
}
我的PersonSettings类只是几个属性。它不是要存储在数据库中的实体,因此我将其标记为“拥有”:
[Owned]
public class PersonSettings
{
public bool NotificationsEnabled { get; set; }
public int GymPassId { get; set; }
}
这些作为json存储在数据库中,我在Person实体配置中使用EF Core转换值对其进行序列化和反序列化:
builder.Property(p => p.Settings).HasConversion(
s => JsonConvert.SerializeObject(s, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }),
s => JsonConvert.DeserializeObject<PersonSettings>(s, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }));
但是当我尝试运行我的应用程序并进行数据库迁移时,出现了错误提示
拥有实体类型“ PersonSettings”需要通过导航从另一个实体类型中引用。向指向“ PersonSettings”的实体类型添加导航。
我应该在这里做什么?我在错误消息上找不到任何内容。不确定与Person作为抽象类是否有关系。
答案 0 :(得分:3)
我也无法复制,但是您不需要在这里拥有类型。
使用拥有的类型是对非标量属性使用JSON序列化的替代。使用“拥有的类型”时,类型与引用它的实体一起存储。因此,由于拥有类型EF会使用“设置_通知启用”和“设置_GymPassId”的单独列创建“人”表。
因此,您可以简单地删除OwnedAttribute,并确保在DbContext中不要将其声明为属性类型为DbSet<PersonSettings>
的实体。
在选择该方案时,通常会使用“拥有的类型”,因此您可以通过各个PersonSettings属性查询数据库。
使用非标量属性的JSON转换对于拥有集合的情况很有用,因为EF Core当前不支持拥有类型的集合。
答案 1 :(得分:0)
我遇到了同样的问题,为我解决的是遵循文档 here。
基本上您想要做的是在您的实体配置中为 OwnsOne
添加一个 Person
:
builder.OwnsOne(p => p.PersonSettings, ps => {
//if need be add additional settings here for NotificationsEnabled and GymPassId
});
这将在 Person 和 PersonSettings 之间创建一个“链接”,迁移生成器使用它来构建脚本。