我有一个值类型“ Address”,该值类型在我的模型中的几个地方使用,例如:Company.PostalAddress,Company.ShippingAddress和Employee.HomeAddress。
数据上下文类中的OnModelCreating方法将如下所示:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Company>(companyBuilder =>
{
companyBuilder.ToTable("Company");
companyBuilder.HasKey(company => company.Id);
companyBuilder.Property(company => company.Id).IsRequired().UseIdentityColumn();
companyBuilder.Property(company => company.Name).IsRequired().HasMaxLength(100);
companyBuilder.OwnsOne(company => company.PostalAddress, addressBuilder =>
{
addressBuilder.Property(address => address.Street).IsRequired().HasMaxLength(100);
addressBuilder.Property(address => address.HouseNumber).IsRequired();
addressBuilder.Property(address => address.HouseNumberExtension).HasMaxLength(20);
addressBuilder.Property(address => address.ZipCode).IsRequired().HasMaxLength(10);
addressBuilder.Property(address => address.City).IsRequired().HasMaxLength(50);
});
companyBuilder.OwnsOne(company => company.VisitingAddress, addressBuilder =>
{
addressBuilder.Property(address => address.Street).IsRequired().HasMaxLength(100);
addressBuilder.Property(address => address.HouseNumber).IsRequired();
addressBuilder.Property(address => address.HouseNumberExtension).HasMaxLength(20);
addressBuilder.Property(address => address.ZipCode).IsRequired().HasMaxLength(10);
addressBuilder.Property(address => address.City).IsRequired().HasMaxLength(50);
});
companyBuilder.OwnsOne(company => company.ShippingAddress, addressBuilder =>
{
addressBuilder.Property(address => address.Street).IsRequired().HasMaxLength(100);
addressBuilder.Property(address => address.HouseNumber).IsRequired();
addressBuilder.Property(address => address.HouseNumberExtension).HasMaxLength(20);
addressBuilder.Property(address => address.ZipCode).IsRequired().HasMaxLength(10);
addressBuilder.Property(address => address.City).IsRequired().HasMaxLength(50);
});
companyBuilder.HasIndex(company => company.Name).IsUnique();
});
builder.Entity<Employee>(employeebuilder =>
{
employeebuilder.ToTable("Employee");
employeebuilder.HasKey(employee => employee.Id);
employeebuilder.Property(employee => employee.Id).IsRequired().UseIdentityColumn();
employeebuilder.Property(employee => employee.FirstName).IsRequired();
employeebuilder.OwnsOne(employee => employee.HomeAddress, addressBuilder =>
{
addressBuilder.Property(address => address.Street).IsRequired().HasMaxLength(100);
addressBuilder.Property(address => address.HouseNumber).IsRequired();
addressBuilder.Property(address => address.HouseNumberExtension).HasMaxLength(20);
addressBuilder.Property(address => address.ZipCode).IsRequired().HasMaxLength(10);
addressBuilder.Property(address => address.City).IsRequired().HasMaxLength(50);
});
});
}
这有很多代码重复,所以我创建了一个私有方法来将Address配置放在一个地方:
private static void Build<T>(OwnedNavigationBuilder<T, Address> addressBuilder) where T : class
{
addressBuilder.Property(address => address.Street).IsRequired().HasMaxLength(100);
addressBuilder.Property(address => address.HouseNumber).IsRequired();
addressBuilder.Property(address => address.HouseNumberExtension).HasMaxLength(20);
addressBuilder.Property(address => address.ZipCode).IsRequired().HasMaxLength(10);
addressBuilder.Property(address => address.City).IsRequired().HasMaxLength(50);
}
这允许我将OnModelCreating方法更改为此:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Company>(companyBuilder =>
{
companyBuilder.ToTable("Company");
companyBuilder.HasKey(company => company.Id);
companyBuilder.Property(company => company.Id).IsRequired().UseIdentityColumn();
companyBuilder.Property(company => company.Name).IsRequired().HasMaxLength(100);
companyBuilder.OwnsOne(company => company.PostalAddress, addressBuilder => Build(addressBuilder));
companyBuilder.OwnsOne(company => company.VisitingAddress, addressBuilder => Build(addressBuilder));
companyBuilder.OwnsOne(company => company.ShippingAddress, addressBuilder => Build(addressBuilder));
companyBuilder.HasIndex(company => company.Name).IsUnique();
});
builder.Entity<Employee>(employeebuilder =>
{
employeebuilder.ToTable("Employee");
employeebuilder.HasKey(employee => employee.Id);
employeebuilder.Property(employee => employee.Id).IsRequired().UseIdentityColumn();
employeebuilder.Property(employee => employee.FirstName).IsRequired();
employeebuilder.OwnsOne(employee => employee.HomeAddress, addressBuilder => Build(addressBuilder));
});
}
但是,Microsoft声明OwnedNavigationBuilder类不能直接在代码中使用,因为它可能“在任何发行版本中未经通知即被更改或删除”。
所以我的问题是:如何避免在不直接调用EF Core内部类的情况下反复重复相同的配置?