EF核心代码优先:通常重命名拥有类型的属性

时间:2019-08-15 20:23:55

标签: c# ef-code-first entity-framework-core ef-migrations owned-types

this documentation之后,我尝试创建一些具有拥有类型的属性的实体:

[Owned]
public class StreetAddress
{
    public string Street { get; set; }
    public string City { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public StreetAddress BillingAddress { get; set; }
    public StreetAddress ShippingAddress { get; set; }
}

按照惯例,EF将在实体Order中创建以下属性:

BillingAddress_Street  
BillingAddress_City  
ShippingAddress_Street  
ShippingAddress_City

我知道有一种重命名列的方法:

modelBuilder.Entity<Order>().OwnsOne(
    o => o.ShippingAddress,
    sa =>
    {
        sa.Property(p => p.Street).HasColumnName("ShipsToStreet");
        sa.Property(p => p.City).HasColumnName("ShipsToCity");
    });

但是,这意味着我将需要将其用于将要生成的每个属性。我认为,这正是我首先要避免使用拥有的类型的原因。

我想做的是创建一个自定义约定,但是,也许使用模型构建器并显式地告诉他如何命名这些属性,以消除下划线等。

我尝试深入研究modelBuilder属性,尝试获取该拥有类型的所有实体,但这似乎不起作用。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:0)

所以我无法入睡,然后重新尝试,并能够解决它:

var ownedTypes = modelBuilder.Model.GetEntityTypes().Where(e => e.IsOwned());
    foreach (var type in ownedTypes)
    {
        foreach (var prop in type.GetProperties())
        {
            var entityName = type.DefiningEntityType.Name;
            var ownedType = type.ClrType;
            var navigationName = type.DefiningNavigationName;
            var propertyName = prop.Name;
            var newColumnName = $"{navigationName}{propertyName}";

            var primaryKeyName = modelBuilder.Model.GetEntityTypes().SingleOrDefault(e => e.Name == entityName)?.GetProperties().SingleOrDefault(p => p.IsPrimaryKey())?.Name;

            if (string.IsNullOrWhiteSpace(primaryKeyName) || propertyName != primaryKeyName)
            {
                modelBuilder.Entity(entityName).OwnsOne(ownedType, navigationName, sa =>
                {
                    sa.Property(propertyName).HasColumnName(newColumnName);
                });
            }
        }
    }

如果您能找到一个更好,更清洁的解决方案,我仍然很高兴。也许我的代码中有一些问题。