1

我使用值对象作为身份,想知道如何最好地处理 EF 核心中的空值。

例如,如果我的员工具有可选头衔(先生、夫人等):

public class Employee
  : Entity,
    IAggregateRoot
{
  public EmployeeTitleId TitleId { get; private set; }
  public EmployeeFirstName FirstName { get; private set; }
  public EmployeeSurname Surname { get; private set; }
   ...
}

我可以在我的代码中到处检查空值,例如

if (employee.TitleId == null) ...

或者我可以使用默认值,例如

if (employee.TitleId.Equals(EmployeeTitleId.None)) ...

实施EmployeeTitleId如下:

public class EmployeeTitleId
  : Value<EmployeeTitleId>
{
  public static readonly EmployeeTitleId None = new EmployeeTitleId();

  protected EmployeeTitleId() { }

  public EmployeeTitleId(Guid value)
  {
    if (value == default)
      throw new ArgumentNullException(nameof(value), "Employee title id cannot be empty");

    Value = value;
  }

  public Guid Value { get; internal set; }

  public static implicit operator Guid(EmployeeTitleId self) => self.Value;

  public static implicit operator EmployeeTitleId(string value)
    => new EmployeeTitleId(Guid.Parse(value));

  public override string ToString() => Value.ToString();
}

我更喜欢第二种方法,因为它看起来更干净,但我不知道这是否矫枉过正。它还需要在实体框架方面进行更多设置,例如:

builder.OwnsOne(_ => _.TitleId).Property(_ => _.Value)
 .HasColumnName("TitleId").HasConversion(v => v == default ? (Guid?) null : v, v => v ?? EmployeeTitleId.None);

这似乎是一种可行的方法,还是我应该坚持检查空值?如果是这样,是否有我可以在实体类型配置中使用的约定,这样我就不必手动设置每个 HasConversion?

4

1 回答 1

0

还有另一种方法可以全局过滤结果。您可以OnModelCreating像这样配置它:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // code omitted for brevity

    modelBuilder.Entity<Employee>().HasQueryFilter(p => p.TitleId == null);
}
于 2020-06-25T19:00:38.957 回答