EF Core 新特性——Owned Entity Types


Owned Entity Types

首先owned entity type是EF Core 2.0的新特性。

至於什么是owned entity types,可以先把他理解為EF Core官方支持的值對象。

值對象

舉一個簡單的例子,你可能在開發中經常遇到,訂單,地址,地址簿的關系:

    public class Order
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public Address Address { get; set; }
    }

    public class AddressBook
    {
        public string FriendName { get; set; }
        public int Id { get; set; }
        public Address Address { get; set; }
    }

    public class Address
    {
        public string City { get; set; }
        public string Street { get; set; }
    }

這個示例里面的Address對象就是典型的值對象,他在訂單中意義是訂單地址,他在電話本里的意義是朋友的住址,就像訂單里的Name和AddressBook中FriendName一樣,你改了就改了,和其他的沒關系,不會因為你改了訂單地址就修改了電話本那個人的地址。

https://www.cnblogs.com/xishuai/p/ddd_valueobject_entityframework.html  這篇大神的文章詳細介紹了值對象在以前版本EF中的設計,現在有了Owned Entity Types,就有了官方實現。

定義

官方文檔上的定義,翻譯過來就是:EF  Core 定義在model中僅用於顯示的其他實體類型Navigation properties被稱為Owned Entity types,就叫做自有實體吧,擁有自有實體的實體叫做擁有者

下面看看怎么在EF Core中實現。

顯式配置

自有實體  在EF Core不能使用慣例方式,可以在OnModelCreating方法中使用OwnsOne方法,或者使用聲明屬性(OwnedAttribute,EF Core 2.1以上版本支持)。

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

modelBuilder.Entity<Order>().OwnsOne(p => p.Address);
//或者使用這種方式
modelBuilder.Entity<Order>().OwnsOne(typeof(Address), "Address");

這在EF Core中時通過影子屬性( shadow property)實現的,

自有實體集合是在EF Core 2.2中實現,可以使用OnModelCreating的OwnsMany方法實現:

modelBuilder.Entity<Distributor>().OwnsMany(p => p.ShippingCenters, a =>
{
    a.HasForeignKey("DistributorId");
    a.Property<int>("Id");
    a.HasKey("DistributorId", "Id");
});

數據庫

慣例情況是:Address屬性在Order表中的名字是:Address_City和Address_Street,你也可以在OwnsOne方法中使用HasColumnName自定義列名,也可以存儲到單獨的表中,下面代碼將地址存到單獨表(orderAddress)中:

modelBuilder.Entity<Order>().OwnsOne(
    o => o.Address,
    sa =>
    {
     sa.ToTable("orderAddress"); sa.Property(p
=> p.Street).HasColumnName("ToStreet"); sa.Property(p => p.City).HasColumnName("ToCity"); });

查詢

 跟普通的屬性一樣:

var order = context.Orders.FirstOrDefault();
Console.WriteLine($"TO: {order.ShippingAddress.City}");

限制

  • 不能生成自有對象的DbSet<T> 。
  • 不能在ModelBuilder中使用自有對象的Entity<T>()。

即將實現:

  • 自有對象不支持繼承。
  • 除非在單獨的表中使用,否則自有對象不能為空。
  • 多個擁有者不能使用同一個自有對象(廢話)。

 以前版本存在問題:

  • EF Core 2.0中除非存在獨立的表中,否則自有對象不能在派生實體類型中聲明。
  • EF Core 2.0和2.1只支持指向自有對象的reference navigations ,在2.2中移除這一限制。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM