首页 > 解决方案 > “拥有的实体类型需要通过导航从另一个实体类型引用”

问题描述

我的应用程序中有一个名为 Person 的实体。有两种类型的用户,学生和教授,从 Person 继承。

每个人都有一个设置属性:

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 作为抽象类有关。

标签: c#entity-frameworkasp.net-coreentity-framework-core

解决方案


我也无法复制,但您在这里不需要拥有类型。

使用 Owned Types 是使用 JSON 序列化非标量属性的替代方法。使用拥有类型时,类型与引用它的实体一起存储。因此,拥有的类型 EF 将创建带有单独列的 Person 表,分别用于 Settings_NotificationEnabled 和 Settings_GymPassId。

因此,您可以简单地删除 OwnedAttribute,并确保您没有将其声明为DbSet<PersonSettings>在 DbContext 中具有类型属性的实体。

至于选择哪个,我通常会在这种情况下使用 Owned Type,因此您可以通过各个 PersonSettings 属性查询数据库。

在有集合的情况下,使用非标量属性的 JSON 转换很有用,因为 EF Core 当前不支持拥有类型的集合。


推荐阅读