zoukankan      html  css  js  c++  java
  • EF-CodeFirst 继承关系TPH、TPT、TPC

    继承关系

    面向对象的三大特征之一:继承 ,在开发中起到了重要的作用。我们的实体本身也是类,继承自然是没有问题。下面开始分析 EF里的继承映射关系TPH、TPT、TPC

    现在我们有这样一个需求,用户里要有一批超级用户,他们有着与生具来的优越。可以体验到更高级的服务。但是超级用户也是用户,可以去继承我们的普通用户类 (其实个人感觉不是很合理,因为我们有UserRole表,给一个超级用户的角色就可以了。这里仅做演示)

    /// <summary>
        /// 超级用户
        /// </summary>
        public class SuperUser : User
        {
            /// <summary>
            /// 超级用户卡号
            /// </summary>
            public string UserNum { get; set; }
        }

    TPH (Table Per Hierarchy)

    TPH是EF中默认的继承映射关系, 我们现在直接Update-DataBase看一下表的结构是什么样的

    image

    可以看到,并没有生成另一张表,而是把SuperUser的属性加到了User表中,等待,貌似多出来一个Discriminator。其实他是用来标识记录是来自哪个实体的。下面做个测试,分别用User和SuperUser实体向表里插入一条数据

    using (Entites aContext = new Entites())
    {
                   
         Core.User.User user = new User()
         {
              Name = "小明",
              UserAddress = new UserAddress() { City = "北京", DynamicAddress = "北京知春路" }
         };
    
          aContext.User.Add(user);
    
          Core.User.SuperUser superUser = new SuperUser()
          {
               Name = "超级小明",
               UserNum = "12346789",
               UserAddress = new UserAddress() { City = "北京", DynamicAddress = "北京798艺术区" }
          };
           aContext.User.Add(superUser);
    
           aContext.SaveChanges();
    
     }

    可以看到Discriminator分别标识了来自什么实体

    image

    其实我们也可以自己去配置,包含字段名和值都可以控制

    public class UserMap : EntityTypeConfiguration<User>
        {
            public UserMap()
            {
              
                Map<Core.User.SuperUser>(u => u.Requires("From").HasValue("From-Super"));
                Map<Core.User.User>(u => u.Requires("From").HasValue("From-User"));
    
            }
        }

    image

    TPT  (Table per Type)

    这个方式是值得推荐的,子类和父类在不同的表中。子类的表只拥有子类的属性。通过相同Id来关联User表

    可以在类上直接 Table(“xxx”),也可以使用 Fluent Api。

    public class UserMap : EntityTypeConfiguration<User>
        {
            public UserMap()
            {
                Map<Core.User.SuperUser>(u => u.ToTable("T_SuperUser"));
            }
        }

    Update-DataBase一下,看看表结构

    image

    再插入数据看一下

    image

    image

    TPC (Table Per Concrete Type)

    这个。。。真的很不想说。存在即合理,还是简单说一下使用方式吧。。使用这种方式父类的属性在子类的表中也会存在。(恶心)  我就不生成了,,看着恶心。。。

    public class UserMap : EntityTypeConfiguration<User>
        {
            public UserMap()
            {
                Map<Core.User.SuperUser>(u=>{
                  u => u.ToTable("T_SuperUser"));
                  u.MapInheritedProperties();
                })
            }
        }

    结束之语

    之前使用复杂类型的时候,我就说过他的某些不好。因为代码上分开了,但是实际表中还是在一起的。TPT的方式很符合我的胃口。也是我一直在想要的扩展表的方式。当然都各有千秋,还是看实际项目的需求。存在即合理,说不定哪一天我也会用上恶心的TPC也说不定

  • 相关阅读:
    JDK的命令详解
    聊天室java socket
    怎么实现利用Java搜索引擎收集网址的程序
    Hibernate实现对多个表进行关联查询
    如何学好J2ME?
    谈谈Java工程师应该具有的知识
    【经营智慧】005.眼光盯着未来
    【成功智慧】002.对任何小事都不要掉以轻心
    【经营智慧】008.要想赚钱,就得打破既有的成见
    【思维智慧】004.砸碎障碍的石头,把它当做钥匙
  • 原文地址:https://www.cnblogs.com/LiangSW/p/5816181.html
Copyright © 2011-2022 走看看