如何将拥有的财产映射到私有字段

我有一个value对象,这意味着它的属性有getters但没有setters。然后,我有了一个具有公共获取者和私有领域的实体。类似于以下内容:

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 Core3。现在在我的IEntityTypeConfiguration<Tenant>实现中,用于配置说名称我没有问题,因为我可以使用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属性映射到私有_settings变量。我尝试在对Property的呼叫之前添加对OwnsOne的呼叫:

...
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);
});

但是当我添加迁移时,出现错误:无法将属性或导航“设置”添加到实体类型“ Tenant”,因为在实体类型“ Tenant”上已经存在具有相同名称的属性或导航,之所以发生这种情况,是因为我两次配置属性“设置”。

那么我该如何实现呢?使用OwnsOne时,HasField相当于什么?提前致谢。

wanlili3646 回答:如何将拥有的财产映射到私有字段

您不需要所有这些HasField调用,因为在EF Core 3.0 Backing fields are used by default中,您的支持字段也遵循EF Core property backing field naming conventions之一,因此EF Core将自动发现并使用它们(尽管您仍然需要Property调用,因为常规情况下不会发现get属性)。

但是可以说,您需要指定相关属性的后备字段。 Property方法无法使用,因为EF Core术语不是属性,而是导航。对于属性构建器,没有类似于HasField的流畅API,因此您必须直接使用可变元数据服务:

builder.OwnsOne(x => x.Settings,y =>
{
    // ...
    y.Metadata.PrincipalToDependent.SetField("_settings");
});

类似于关系导航属性。相应构建器的Metadata属性返回IMutableForegnKey对象。 PrincipalToDependentDependentToPrincipal属性返回IMutableNavigation对象,可用于配置相应的导航属性。

本文链接:https://www.f2er.com/3142327.html

大家都在问