如何将拥有的 属性 映射到私有字段
How to map an owned property to a private field
我有一个值对象,这意味着它的属性有 getter 但没有 setter。然后我有一个带有 public getter 和私有字段的实体。类似于以下内容:
public class Settings {
private string _instance;
private string _domain;
public Settings(string instance, string domain) {
_instance = instance;
_domain = domain;
}
private Settings() {
_instance = default!;
_domain = default!;
}
public string Instance => _instance;
public string Domain => _domain;
}
public class Tenant {
private Guid _id;
private string _name;
private Settings _settings;
public Tenant(string name) {
_id = Guid.Empty;
_name = name;
_settings = new Settings("etc", "etc");
}
private Tenant() {
_id = default;
_name = default!;
_settings = default!;
}
public Guid Id => _id;
public string Name => _name;
public Settings => _settings;
protected void OnSettingsChanged() {
// do stuff like adding domain events and sending notifications
}
public void ChangeSetting(Settings newSettings) {
// do some model validation
_settings = newSettings;
OnSettingsChanged();
}
}
我正在使用 C# 8、.NET Core 3 和 Entity Frmework Core 3。现在在我的 IEntityTypeConfiguration<Tenant>
实现中,配置 say Name 没问题,因为我可以使用 HasField 并传递私人名称 属性。但这不适用于设置。在那里,我使用 OwnsOne,但没有可用的 HasField 属性。
builder.Property(x => x.Name)
.HasField("_name")
.HasMaxLength(100);
builder.OwnsOne(x.Settings, y => {
y.Property(z => z.Instance)
.HasField("_instance")
.IsRequired(true);
y.Property(z => z.Domain)
.HasField("_domain")
.IsRequired(true);
//y.HasField() ??
});
但是我找不到告诉 EF 设置 属性 应该映射到私有 _settings
变量的方法。我尝试在调用 OwnsOne
:
之前添加对 Property
的调用
...
builder.Property(x => x.Settings)
.HasField("_settings");
builder.OwnsOne(x.Settings, y => {
y.Property(z => z.Instance)
.HasField("_instance")
.IsRequired(true);
y.Property(z => z.Domain)
.HasField("_domain")
.IsRequired(true);
});
但是当我添加迁移时,我得到一个错误:属性 或导航 'Settings' 无法添加到实体类型 'Tenant' 因为 属性或实体类型 'Tenant' 上已存在同名导航,我想这是因为我配置了两次 属性 设置。
那么我如何实现这一点,使用 OwnsOne 时 HasField 的等效项是什么?提前致谢。
您不需要所有这些 HasField
调用,因为在 EF Core 3.0 Backing fields are used by default and also your backing fields follow one of the EF Core property backing field naming conventions 中,因此 EF Core 会自动发现并使用它们(您仍然需要 Property
调用,因为仅获取未按约定发现的属性)。
但是假设您需要指定相关 属性 的支持字段。无法使用 Property
方法,因为根据 EF Core 术语,这些不是属性,而是 navigations。对于 属性 构建器,没有类似于 HasField
的流畅 API,因此您必须直接使用可变元数据服务:
builder.OwnsOne(x => x.Settings, y =>
{
// ...
y.Metadata.PrincipalToDependent.SetField("_settings");
});
它类似于关系导航属性。 Metadata
属性 对应的builder returns IMutableForegnKey
对象。 PrincipalToDependent
和 DependentToPrincipal
属性 return IMutableNavigation
可用于配置相应导航的对象 属性。
我有一个值对象,这意味着它的属性有 getter 但没有 setter。然后我有一个带有 public getter 和私有字段的实体。类似于以下内容:
public class Settings {
private string _instance;
private string _domain;
public Settings(string instance, string domain) {
_instance = instance;
_domain = domain;
}
private Settings() {
_instance = default!;
_domain = default!;
}
public string Instance => _instance;
public string Domain => _domain;
}
public class Tenant {
private Guid _id;
private string _name;
private Settings _settings;
public Tenant(string name) {
_id = Guid.Empty;
_name = name;
_settings = new Settings("etc", "etc");
}
private Tenant() {
_id = default;
_name = default!;
_settings = default!;
}
public Guid Id => _id;
public string Name => _name;
public Settings => _settings;
protected void OnSettingsChanged() {
// do stuff like adding domain events and sending notifications
}
public void ChangeSetting(Settings newSettings) {
// do some model validation
_settings = newSettings;
OnSettingsChanged();
}
}
我正在使用 C# 8、.NET Core 3 和 Entity Frmework Core 3。现在在我的 IEntityTypeConfiguration<Tenant>
实现中,配置 say Name 没问题,因为我可以使用 HasField 并传递私人名称 属性。但这不适用于设置。在那里,我使用 OwnsOne,但没有可用的 HasField 属性。
builder.Property(x => x.Name)
.HasField("_name")
.HasMaxLength(100);
builder.OwnsOne(x.Settings, y => {
y.Property(z => z.Instance)
.HasField("_instance")
.IsRequired(true);
y.Property(z => z.Domain)
.HasField("_domain")
.IsRequired(true);
//y.HasField() ??
});
但是我找不到告诉 EF 设置 属性 应该映射到私有 _settings
变量的方法。我尝试在调用 OwnsOne
:
Property
的调用
...
builder.Property(x => x.Settings)
.HasField("_settings");
builder.OwnsOne(x.Settings, y => {
y.Property(z => z.Instance)
.HasField("_instance")
.IsRequired(true);
y.Property(z => z.Domain)
.HasField("_domain")
.IsRequired(true);
});
但是当我添加迁移时,我得到一个错误:属性 或导航 'Settings' 无法添加到实体类型 'Tenant' 因为 属性或实体类型 'Tenant' 上已存在同名导航,我想这是因为我配置了两次 属性 设置。
那么我如何实现这一点,使用 OwnsOne 时 HasField 的等效项是什么?提前致谢。
您不需要所有这些 HasField
调用,因为在 EF Core 3.0 Backing fields are used by default and also your backing fields follow one of the EF Core property backing field naming conventions 中,因此 EF Core 会自动发现并使用它们(您仍然需要 Property
调用,因为仅获取未按约定发现的属性)。
但是假设您需要指定相关 属性 的支持字段。无法使用 Property
方法,因为根据 EF Core 术语,这些不是属性,而是 navigations。对于 属性 构建器,没有类似于 HasField
的流畅 API,因此您必须直接使用可变元数据服务:
builder.OwnsOne(x => x.Settings, y =>
{
// ...
y.Metadata.PrincipalToDependent.SetField("_settings");
});
它类似于关系导航属性。 Metadata
属性 对应的builder returns IMutableForegnKey
对象。 PrincipalToDependent
和 DependentToPrincipal
属性 return IMutableNavigation
可用于配置相应导航的对象 属性。