基本上sql中要表示继承关系有3中方式.

分别是,1表继承(TPH),2表继承(TPC),3表继承(TPT)

1表 :

Person

id  type  name  classroom  office

1  student  keat       1B      null

2      teacher  xinyao    null       Lv2-T2

好处是不用 inner join 快,坏处是null 很多,浪费空间, column很长不好看。

2表:

这个很瞎不要学 .. , 大概就是没有父表,字表很多,但是每个column都重复写...无言

3表: (3只是代号,其实是看子类多少就多少表,子表的 id 是跟父表一样的)

Person

id  name

Student

id  classroom

Teacher

id  office

这样就没有null了,只是要inner join 会慢

entity 是用 Fluent API 来实现的

3表方式

    [Table("person")]
public class Person
{
[Key]
public Int32 id { get; set; }
public string name { get; set; }
}
//子类不要写 [table("")]public class Student : Person
{
public string classroom { get; set; }
}public class Teacher : Person
{
public string office { get; set; }
}

Fluent API

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>(). //对Person
Map<Student>(s => s.ToTable("student")). //map 另外2个table , "student" 是tableName
Map<Teacher>(t => t.ToTable("teacher"));
base.OnModelCreating(modelBuilder);
}

insert 的话直接实例化字类就可以了

    db.students.Add(new Student
{
name = "keatkeat",
classroom = "1B"
});
db.SaveChanges();

1表方式 :

    [Table("person")]
public class Person
{
[Key]
public Int32 id { get; set; }
public string name { get; set; }
     //publick string type {get ;set;} //这里是不可以这样写的,type是entity 和 sql 秘密沟通用的
}
/*
子类千万不要写 [Table()] 了
*/
public class Student : Person
{
public string classroom { get; set; }
}
public class Teacher : Person
{
public string office { get; set; }
}

Fluent API

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.Map<Student>(s => s.Requires("type").HasValue("student"))
.Map<Teacher>(m => m.Requires("type").HasValue("teacher"));
base.OnModelCreating(modelBuilder);
}

属性 type 是 sql 和 EF 秘密沟通的值,我们是不能获取的。

在获取数据或者做过滤的时候

var commentss = db.users.OfType<Salesman>().Where(s => s.salesmanSpecialColumn == "abc").ToList();
var comments = db.comments.Where(c => c.user is Salesman && (c.user as Salesman).salesmanSpecialColumn == "abc").ToList();

主要是用了 OfType , is , as 来强转

另外 WebAPI 2 , OData v4 的 request url 是这样写的 :

/api/comments?$filter=user/EFDB.Salesman/salesmanSpecialColumn eq 'abc'

for expand : /api/Singles?$expand=abstracts($expand=EFDB.AA/childs)

另外, TPT 虽然比较 OO 不过也常出现Bug,尤其是你的继承很深很宽.

TPT还有个坏处就是 join 表会很慢 。

TPT 在做 checkconcurrent 时要注意,最好在基表加一个rowVersion column , 在 saveChanges 时set 这个column to isModified , 不然并出来的语句会有问题的。

所以通常我们还是会使用 TPH 来做项目

TPH 也是有问题的,虽然select不用Join,

nullable 引起的问题 :浪费空间,sql table 不好看 , 对索引不利 , 不能强制验证不能为null.

(For MSSQL)

此外nullable也不方便set UNIQUE (虽然可以用 filter fix)

还有一种是类的继承 (完全没有写  data annotations vs fluent api)

它表示在所有表都有这个基类的属性

通常我们可以用来做 rowVersion , lastModified, createDatetime 这类基本的东西。

需要注意的是如果有 creator_id (比如记入administrator_id) 遇到有关联的表有些情况要使用  [InverseProperty("administrator")] 来指定哦 ! 我之前就是被这个坑了一下。

还有这种继承不能放在抽象类上(我没有研究为什么,就有bug). 所以比如有rowVersion 那些,在多层继承的类的最上层基类,直接copy paste 属性进去而不要使用继承.

更新 : 2015-07-11

抽象累被 OData json 化返回到前台,每个资源都会附带一个 "'@odata.type' : '#EFDB.Member'" 来表明它是属于那个子类。

当我们在做 POST,PUT 的时候也是同样的道理,我们要告诉OData 明确的子类类型,不然OData是没有办法判断出来的。所以 POST 的json 也必须含有 "@odata.type" !

更新 : 2015-09-26

类型一但创建了就不能够换了,EF并不支持,比如你想把 Teacher 换成 Student =.=”

Entity Framework with MySQL 学习笔记一(继承)的更多相关文章

  1. Entity Framework with MySQL 学习笔记一(安装)

    声明 :  数据库是Mysql,本人的程度只到会写sql语句(不会储蓄过程), c# 会基本的ADO.NET数据库访问,LINQ基础. 这篇只做个人学习|温习作用. 新手可以参考,也请高手指正错误, ...

  2. Entity Framework with MySQL 学习笔记一(乐观并发)

    在做项目时,通常我们对乐观并发有几种处理模式 1. 告诉用户此数据已被其他人捷足先登,更改了.你就算新一下重来吧. 2.直接把数据覆盖上去,我最大. 3.用被人的数据. 这里给出 code first ...

  3. Entity Framework with MySQL 学习笔记一(关系整理版)

    1-1 设置 //DataAnnotation 1-1 | 1-0 table //SQLtable : member , columns : memberId, name //SQL basic l ...

  4. Entity Framework with MySQL 学习笔记一(insert,update,delete)

    先说说 insert 吧. 当EF执行insert时,如果我们传入的对象是有关联(1对多等)的话,它会执行多个语句 insert到多个表, 并且再select出来填充我们的属性(因为有些column默 ...

  5. Entity Framework with MySQL 学习笔记一(查看EF和SQL请求日志)

    做数据库的一向来都会很注意请求的次数还有语句.这关系到很多性能的问题. 因此在使用EF的时候如果不了解原理很可能会搞出很糟糕的请求. 所以呢,在还没有搞懂EF前最基本的是你得"看得见&quo ...

  6. Entity Framework with MySQL 学习笔记一(拦截)

    参考 : http://msdn.microsoft.com/en-us/data/dn469464.aspx EF 允许我们在发送SQL请求和返回数据时做一些拦截的动作 比如可以自定义写 log , ...

  7. Entity Framework with MySQL 学习笔记一(验证标签)

    直接上代码 [Table("single_table")] public class SingleTable { [Key] public Int32 id { get; set; ...

  8. Entity Framework with MySQL 学习笔记一(复杂类型 Complex Types)

    有时候我们希望在sql一个表里面的column, 一部分被分化成另一个class 典型的例子是 Address 直接看代码: [Table("member")] public cl ...

  9. Entity Framework with MySQL 学习笔记一(关系)

    这一篇说说 EF Fluent API 和 DataAnnotations 参考 : http://msdn.microsoft.com/en-us/data/jj591617.aspx http:/ ...

随机推荐

  1. 哈希表的C语言实现

    首先介绍一下什么是哈希表.同线性表.树一样,哈希表也是一种数据结构,理想情况下可以不需要任何比较,一次存取便能得到所查记录.所以它的优点就是查找特定记录的速度快.因为哈希表是基于数组的,所以创建后就难 ...

  2. Controlling How NSThread and NSRunLoop Exit

    http://shaheengandhi.com/controlling-thread-exit/ While most concurrency can be dealt with by using ...

  3. 高频交易策略之Penny Jump

    今天假设有一个笨笨的大型机构投资人(共同基金,银行,退休基金....),他想要买进一只股票,但又不想挂市价买进,所以就在市场里面挂了一张要买进的大单.这时候所有市场里面的人都会看的到limit ord ...

  4. 用js实现的刷新页面

    一.先来看一个简单的例子: 下面以三个页面分别命名为frame.html.top.html.bottom.html为例来具体说明如何做. frame.html 由上(top.html)下(bottom ...

  5. vector的含义

    数学中,vector(向量)表示一个量,由大小和方向构成.比如坐标中的一个带箭头的线段 -- 它1厘米长,正弦值六分之一π(30度角). 计算机的c++.java中,vector表示一种一维的数组.比 ...

  6. Oracle常用脚本——通过RMAN配置RAC环境的分布式磁带机

    RAC的两个节点:node1,node2 RAC的两个实例:dbrac1,dbrac2 用户,密码的东西大家看看就懂了.设置成8能通道的. #!/bin/bash rman target / < ...

  7. 第二节,CCSpriteBatchNode CCSpriteFrameCache

    1,CCSpriteBatchNode 精灵集合类 其中Batch的英文含义是一批,一群的意思.他的对象常常包含了许多的精灵对象,这些精灵对象有一个共同的特点,那就是使用同一张文理图片.虽然是同一个纹 ...

  8. rman catalog (rman 恢复目录)

    受控制文件大小的限制,一般rman需要用rman catalog来管理及存放备份信息: 这里介绍一下创建rman catalog的步骤: C:\Documents andSettings\Admini ...

  9. JAVA/PHP/C#版RSA验签--转

    本文是上一篇文章的兄弟篇,上篇文章介绍了客户端的sdk中如何基于JAVA/PHP/C#使用RSA私钥签名,然后服务端基于JAVA使用RSA公钥验签,客户端签名/服务端验签的模式只能帮助服务端检查客户端 ...

  10. 01-资料管理器(Directory/DirectoryInfo操作文件夹类)

    public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Loa ...