EF Core:多属性值对象

作者:微信公众号:【架构师老卢】
3-3 8:30
25

概述:在本文中,我们将通过演练一个示例来探讨如何在 EF Core 中使用多属性值对象。本文不仅将说明值对象的力量,还将展示它们如何导致更具表现力的领域模型。考虑电子商务域中的值对象。在此上下文中,地址不仅仅是一个字符串,它还包含各种元素,例如街道、城市、州和邮政编码。将其作为定义订单需要运送到哪里的原子信息进行处理至关重要。以下是我们对此的建模方式:Addresspublic class Order {     public int Id { get; set; }     public Address ShippingAddress { get; set; }     // ..

在本文中,我们将通过演练一个示例来探讨如何在 EF Core 中使用多属性值对象。本文不仅将说明值对象的力量,还将展示它们如何导致更具表现力的领域模型。

考虑电子商务域中的值对象。在此上下文中,地址不仅仅是一个字符串,它还包含各种元素,例如街道、城市、州和邮政编码。将其作为定义订单需要运送到哪里的原子信息进行处理至关重要。以下是我们对此的建模方式:Address

public class Order  
{  
    public int Id { get; set; }  
  
    public Address ShippingAddress { get; set; }  
  
    // ... remaining properties for an Order  
}  
  
public class Address  
{  
    public string Street { get; private set; }  
  
    public string City { get; private set; }  
  
    public string State { get; private set; }  
  
    public string PostalCode { get; private set; }  
      
    public Address(string street, string city, string state, string postalCode)  
    {  
        Street = street;  
        City = city;  
        State = state;  
        PostalCode = postalCode;  
    }  
      
    // Additional methods to handle address-related operations could go here  
}

在上面的代码片段中,实体包含一个 value 对象。该类包含多个属性,每个属性表示地址的一部分,以及一个构造函数,用于确保创建对象时包含其所有必需的部分。OrderAddressAddressAddress

我们将了解如何配置 EF Core 以将此值对象映射到数据库架构:

protected override void OnModelCreating(ModelBuilder modelBuilder)  
{  
    modelBuilder.Entity<Order>(order =>  
    {  
        order.ToTable("Orders").HasKey(o => o.Id);  
        order.OwnsOne(o => o.ShippingAddress, a =>  
        {  
            a.Property(p => p.Street).HasColumnName("ShippingStreet");  
  
            a.Property(p => p.City).HasColumnName("ShippingCity");  
  
            a.Property(p => p.State).HasColumnName("ShippingState");  
  
            a.Property(p => p.PostalCode).HasColumnName("ShippingPostalCode");  
        });  
    });  
      
    base.OnModelCreating(modelBuilder);  
}

在该方法中,我们指示 EF Core 使用该方法指示实体具有值对象。然后,我们将对象的每个属性映射到表中的一列。OnModelCreatingOrderAddressOwnsOneAddressOrders

通过将地址视为值对象,我们将与地址相关的所有逻辑集中在一个地方。这使得代码不易出错,并确保地址的概念在整个系统中一致地表示。此外,值对象的使用可以简化更改或重构域概念的过程,因为这些更改已本地化到值对象本身。

数据库架构

在 Entity Framework Core 中,OwnsOne 方法用于定义实体与其拥有类型之间的一对一关系,其中拥有的实体在概念上是所有者的一部分,而不是单独的独立实体。配置此类关系时,默认情况下,EF Core 会将拥有类型的属性映射到数据库中所有者的表,这种技术称为表拆分。

在我们的示例中,实体拥有一个值对象。这意味着 的属性将包含在“Orders”表中,默认列名以导航属性名称为前缀,从而产生类似“ShippingAddress_Street”和“ShippingAddress_City”的列名。OrderAddressAddress

但是,我们使用该方法覆盖了这些默认列名,以直接在“Orders”表中具有更简洁的名称,例如“ShippingStreet”和“ShippingCity”,从而根据我们的域模型简化数据库架构。HasColumnName

相关留言评论
昵称:
邮箱:
阅读排行