将导航属性映射到主表

时间:2019-07-18 11:08:16

标签: c# entity-framework-core

我有一个类Contract,具有两个属性TotalAmountInstallmentAmount

public class Contract
{
    public int ContractId { get; set; }
    public Amount TotalAmount { get; set; }
    public Amount InstallmentAmount { get; set; }
    //other Amounts
}

public class Amount
{
    public decimal Value { get; set; }
    public string Currency { get; set; }
} 

是否可以配置实体框架,以便它可以创建具有以下结构的表Contract

------------------------------------------------------------
| ContractId | TotalAmountValue | TotalAmountCurrency | ... 
|     999    |       1000       |         USD         | ...
------------------------------------------------------------  

1 个答案:

答案 0 :(得分:3)

回答您的具体问题。通过将Amount类映射为owned entity type,可以实现您的要求。

最简单的方法是使用[Owned]属性:

[Owned] // <--
public class Amount
{
    public decimal Value { get; set; }
    public string Currency { get; set; }
}

或流畅的API:

modelBuilder.Owned<Amount>();

默认情况下,此操作将创建一个有问题的表,但列名将为TotalAmount_ValueTotalAmount_Currency等。如果可以,那么您就完成了。

如果要删除列名中的下划线,则需要为每个OwnsOne属性使用Contract.Amount流利的API,然后为每个Property(...).HasColumnName(...)属性使用Amount 。您可以使用EF Core元数据服务循环执行该操作,而不必手动执行该操作。例如:

modelBuilder.Entity<Contract>(builder =>
{
    var amounts = builder.Metadata.GetNavigations()
        .Where(n => n.ClrType == typeof(Amount));
    foreach (var amount in amounts)
    {
        var amountBuilder = builder.OwnsOne(amount.ClrType, amount.Name);
        var amountProperties = amountBuilder.OwnedEntityType.GetProperties()
            .Where(p => !p.IsKey());
        foreach (var property in amountProperties)
            amountBuilder.Property(property.Name).HasColumnName(amount.Name + property.Name);
    }
});