zoukankan      html  css  js  c++  java
  • 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中移除这一限制。
  • 相关阅读:
    c++函数库中一些实用的函数
    全排列
    最小生成树
    线段树初步
    各种刷题网站
    KMP初步
    【转载】在Linux系统下用dd命令制作ISO镜像U盘启动盘
    【转载】windows linux cent 7 制作U盘 启动盘
    pytho命名规范
    【转载】python中not,and,or的优先级问题及用法
  • 原文地址:https://www.cnblogs.com/indexlang/p/10174485.html
Copyright © 2011-2022 走看看