[ActiveRecord] 之六:继承
来源:互联网 发布:淘宝怎么解决管控纪录 编辑:程序博客网 时间:2024/05/01 06:32
1. 无关联继承
public class Person{ private int id; [PrimaryKey(PrimaryKeyType.Identity)] public int Id { get { return id; } set { id = value; } } private string name; [Property(NotNull=true)] public string Name { get { return name; } set { name = value; } }}[ActiveRecord]public class Student : Person{ private int grade; [Property] public int Grade { get { return grade; } set { grade = value; } }}[ActiveRecord]public class Teacher : Person{ private string job; [Property] public string Job { get { return job; } set { job = value; } }}
调用 ActiveRecordStarter.CreateSchema(); ,你会发现数据库里面分别生成了 Student 和 Teacher 数据表,每个表都拥有基类(Person)的字段,相互没有关联。这种继承方式下,我们无法通过 Find(typeof(Person)) 来返回所有人(Student & Teacher)。严格来说,我们根本无法调用此方法,因为我们不能为 Person 添加 ActiveRecordAttribute。
此方式仅仅是为了代码重用而已,并没有业务上的关联。
== 数据表结构 ==
Student Table{ Id Name Grade}Teacher Table{ Id Name Job}
执行插入对象测试代码
Student s = new Student();s.Name = "student1";s.Grade = 2;ActiveRecordMediator.Create(s);Teacher t = new Teacher();t.Name = "teacher1";t.Job = "班主任";ActiveRecordMediator.Create(t);
结果
Student Table{ Id = 1 Name = "student1" Grade = 2}Teacher Table{ Id = 1 Name = "teacher1" Job = "班主任"}
2. 单表关联继承
我们使用 ActiveRecordAttribute 内置属性更改上面的例子,使其成为关联继承。
[ActiveRecord(DiscriminatorColumn = "Type", DiscriminatorType = "String", DiscriminatorValue = "Person")]public class Person{ private int id; [PrimaryKey(PrimaryKeyType.Identity)] public int Id { get { return id; } set { id = value; } } private string name; [Property(NotNull=true)] public string Name { get { return name; } set { name = value; } }}[ActiveRecord(DiscriminatorValue = "Student")]public class Student : Person{ private int grade; [Property] public int Grade { get { return grade; } set { grade = value; } }}[ActiveRecord(DiscriminatorValue = "Teacher")]public class Teacher : Person{ private string grade; [Property] public string Job { get { return grade; } set { grade = value; } }}
你会发现数据库里面仅生成了一个Person表。
== 数据表结构 ==
Student Person{ Id Type // 由 Person[DiscriminatorColumn...] 特性生成! Name Grade Job}
执行插入对象测试代码
结果
Person Table{ // Record 1----------------- Id = 1 Type = "Student" Name = "student1" Grade = 2 Job = <NULL> // Record 2----------------- Id = 2 Type = "Teacher" Name = "teacher1" Grade = <NULL> Job = "办主任"}
在基类定义一个 DiscriminatorColumn 特性,子类通过写入不同的 DiscriminatorValue 来达到区分不同子类型的目的。
这种方式解决了多态查询的问题,但当子类新增属性较多,而且多个子类属性差别较大的情况下,数据库空间浪费会比较严重。同时由于对于不属于当前类的数据库字段插入NULL,可能会造成插入时发生错误,触发异常(比如我们将 Teacher.Job 的特性改为 Property(NotNull=true),那么我们保存Student对象到数据库时就会触发异常)。
我们对基类和子类进行查询测试
foreach Person p in (Person[])ActiveRecordMediator.FindAll(typeof(Person))){ Console.WriteLine("Person {0}:{1}", p.Id, p.Name);}foreach (Student p2 in (Student[])ActiveRecordMediator.FindAll(typeof(Student))){ Console.WriteLine("Student {0}:{1}", p2.Id, p2.Name);}foreach (Teacher p3 in (Teacher[])ActiveRecordMediator.FindAll(typeof(Teacher))){ Console.WriteLine("Teacher {0}:{1}", p3.Id, p3.Name);}
输出
Person 1:student1
Person 2:teacher1
Student 1:student1
Teacher 2:teacher1
建议你继续往下看,或许下面的方式更适合你。
3. 多表关联继承
[ActiveRecord, JoinedBase]public class Person{ private int id; [PrimaryKey(PrimaryKeyType.Identity)] public int Id { get { return id; } set { id = value; } } private string name; [Property(NotNull=true)] public string Name { get { return name; } set { name = value; } }}[ActiveRecord]public class Student : Person{ [JoinedKey("Id")] public int StudentId { get { return base.Id; } set { base.Id= value; } } private int grade; [Property] public int Grade { get { return grade; } set { grade = value; } }}[ActiveRecord]public class Teacher : Person{ [JoinedKey("Id")] public int TeacherId { get { return base.Id; } set { base.Id= value; } } private string grade; [Property] public string Job { get { return grade; } set { grade = value; } }}
我们注意到为 Person 添加了 ActiveRecordAttribute 和 JoinedBaseAttribute 特性,同时为子类 Student 和 Teacher 添加了一个附加了 JoinedKeyAttribute 的 Id 字段。此继承模式会分别生成 Person、Student 和 Teacher 三个数据表。Person 存储了基类的所有字段,子类表仅包含子类增加的属性和Id映射字段。此继承方式下,我们查找 Person 时,会同时返回 Student 和 Teacher记录。
== 数据表结构 ==
Person Table{ Id Name}Student Table{ StudentId Grade}Teacher Table{ TeacherId Job}
执行插入对象测试代码
结果
Person Table{ // Record 1--- Id = 1 Name = "student1" // Record 1--- Id = 2 Name = "teacher1"}Student Table{ Id = 1 Grade = 2}Teacher Table{ Id = 2 Job = "班主任"}
- [ActiveRecord] 之六:继承
- 使用Castle.ActiveRecord的注意事项之三:继承
- maven学习之六继承
- [ActiveRecord] 之三:SessionScope
- [ActiveRecord] 之四:Cascade
- [ActiveRecord] 之五:ActiveRecordMediator
- [ActiveRecord] 之八:Queries
- Yii2学习之ActiveRecord
- Castle学习系列(六)---ActiveRecord属性校验
- 使用Castle.ActiveRecord的注意事项三:继承
- 精通Hibernate之映射继承关系六
- javascript 的 继承(六) 之 寄生组合式继承
- ActiveRecord
- ActiveRecord
- ActiveRecord
- [ActiveRecord] 之二:常用方法
- JFinal之ActiveRecord开发示例
- Jfinal之ActiveRecord(上)
- android滑动基础篇
- [ActiveRecord] 之五:ActiveRecordMediator
- ExpandableListView基本实现—能运行
- 读取RSS源的天气预报Web Server实现
- (2011.07.04-2011.07.09)六天的学习小记
- [ActiveRecord] 之六:继承
- 根据查询的关键字,实现获取百度指定页数的搜索结果的信息(网页地址,标题,摘要,并有排序的说明)
- C++图像处理 -- 图像颜色混合(中)
- 字节对齐
- 免费教程大型网站整理大集合
- 目标习惯和目标方式
- 集合
- [ActiveRecord] 之七:多数据库配置
- [ActiveRecord] 之八:Queries