代码改变世界

ORM映射框架总结--映射桥梁

2010-04-02 12:49  贺臣  阅读(9049)  评论(18编辑  收藏  举报

1.       感言

写博客之前先自我吹嘘一下,给这些文章来些自我介绍。

半年前自己借用了5个多月的业务时间写了一个个人ORM映射框架。在之前的博

客中也有过写过该框架的相关介绍。半年前的那个ORM只不过是自己想象的关系映射的一个雏形,那一段曾经让自己骄傲过得代码的确存在着太多的问题,但是我始终没有放弃过对它的修改。又过了半年,这个ORM映射框架在之前的基础上有了很大的改进。在此与大家分享一下,希望大家共同探讨,共同学习。

 

2.       框架整体介绍

说道这里,其实这个ORM框架仍然存在这很大的问题。不过这个是自己的第二期目标,到现在这个程度算是完成了.

目前出现的ORM 框架还是比较多的。本人写这个ORM不是为了说要推翻某个理论或者要和Linq,Nhibernate 一教高下,目前一个人之力几乎不可能。写此框架只是为了更近一步的了解程序架构。

 

设计思路其实很简单,和其余的ORM框架一样。通过某种关系来维持实体对象和数据库之间的关系,然后通过实体对象的操作来实现数据库的操作。

ORM是通过使用描述对象和数据库之间映射的元数据,在我们想到描述的时候自然就想到了xml和特性(Attribute).目前的ORM框架中,Nhibernate 就是典型的使用xml文件作为描述实体对象的映射框架,而大名鼎鼎的Linq 则是使用特性(Attribute) 来描述的。

    我自己写的这个出于学习特性这一知识,于是采用了特性(Attribute)来描述实体对象。

 

ORM 映射功能的实现组要由如下几个组建组成:

(1)       实体数据库 映射特性关系

(2)       实体分析器

(3)       Sql 语句生成组建

(4)       数据库操作库

 

框架整体结构图:


 

3.       实体数据库映射特性

对于数据库和实体之间关系的描述,这个框架中使用了四个特性来描述。

TableAttribute 特性

字段名

作用

name

数据表名

该字段用于描述数据库对应表的名称,而且该值最好与

数据表名大小写相同。该值有两种类型。

(1)直接自定表的名称

(2)[数据库名].[表名]

如果是(2)情况,则需要分割字符串,将数据库名分割

出来赋值给dBName

dBName

数据库名

该字段用于描述数据的名称,而且该值最好与

数据库名称大小写相同

primaryKeyName

主键字段名

该实体必须指定对应数据库表的主键

information

表实体描述信息

默认为""

isInternal

表实体是否国际化

默认为false

true 国际化 false 不国际化

version

表实体版本号

默认为 "V1.0"

 

 

特性源码:

    1 /**

  2  * 2010-1-28
  3  * 
  4  * 情 缘
  5  * 
  6  * 实体表特性,用于描述实体和数据库表之间的映射关系
  7  * 
  8  * 该特性类使用 sealed 修改,说明该类不能够再被继承。
  9  * 
 10  * */
 11 
 12 using System;
 13 
 14 namespace CommonData.Model.Core
 15 {
 16     public sealed class TableAttribute:Attribute
 17     {
 18         /// <summary>
 19         /// 数据表名
 20         /// 该字段用于描述数据库对应表的名称,而且该值最好与
 21         /// 数据表名大小写相同。该值有两种类型。
 22         /// (1)直接自定表的名称
 23         /// (2)[数据库名].[表名]
 24         /// 如果是(2)情况,则需要分割字符串,将数据库名分割
 25         /// 出来赋值给dBName
 26         /// </summary>
 27         private string name;
 28 
 29         /// <summary>
 30         /// 数据库名
 31         /// 该字段用于描述数据的名称,而且该值最好与
 32         /// 数据库名称大小写相同
 33         /// </summary>
 34         private string dBName;
 35 
 36         /// <summary>
 37         /// 主键字段名
 38         /// 该实体必须指定对应数据库表的主键
 39         /// </summary>
 40         private string primaryKeyName = "";
 41 
 42         /// <summary>
 43         /// 表实体描述信息
 44         /// 默认为""
 45         /// </summary>
 46         private string information = "";
 47 
 48         /// <summary>
 49         /// 表实体是否国际化
 50         /// 默认为false
 51         /// true 国际化 false 不国际化
 52         /// </summary>
 53         private bool isInternal = false;
 54 
 55         /// <summary>
 56         /// 表实体版本号
 57         /// 默认为 "V1.0"
 58         /// </summary>
 59         private string version = "V1.0";
 60 
 61 
 62         /// <summary>
 63         /// 无参数构造方法
 64         /// </summary>
 65         public TableAttribute()
 66         {
 67 
 68         }
 69 
 70         /// <summary>
 71         /// 部分参数构造方法,构造改表特性的实体类
 72         /// 并实现部分字段的初始化
 73         /// </summary>
 74         /// <param name="name">数据表名</param>
 75         /// <param name="dBName">数据库名</param>
 76         /// <param name="primaryKeyName">主键字段名</param>
 77         /// <param name="isInternal">表实体是否国际化</param>
 78         public TableAttribute(string name, 
 79             string dBName, 
 80             string primaryKeyName, 
 81             bool isInternal) 
 82         {
 83             this.name = name;
 84             this.dBName = dBName;
 85             this.primaryKeyName = primaryKeyName;
 86             this.isInternal = isInternal;
 87         }
 88 
 89         /// <summary>
 90         /// 全参数构造方法,构造改表特性的实体类
 91         /// 并实现所有字段的初始化
 92         /// </summary>
 93         /// <param name="name">数据表名</param>
 94         /// <param name="dBName">数据库名</param>
 95         /// <param name="primaryKeyName">主键字段名</param>
 96         /// <param name="information">表实体描述信息</param>
 97         /// <param name="isInternal">表实体是否国际化</param>
 98         /// <param name="version">表实体版本号</param>
 99         public TableAttribute(string name, 
100             string dBName, 
101             string primaryKeyName, 
102             string information, 
103             bool isInternal, 
104             string version)
105         {
106             this.name = name;
107             this.dBName = dBName;
108             this.primaryKeyName = primaryKeyName;
109             this.information = information;
110             this.isInternal = isInternal;
111             this.version = version;
112         }
113 
114         /// <summary>
115         /// 数据表名
116         /// </summary>
117         public string Name
118         {
119             get { return name; }
120             set { name = value; }
121         }
122         
123         /// <summary>
124         /// 数据库名
125         /// </summary>
126         public string DBName
127         {
128             get { return dBName; }
129             set { dBName = value; }
130         }
131         
132         /// <summary>
133         /// 主键字段名
134         /// </summary>
135         public string PrimaryKeyName
136         {
137             get { return primaryKeyName; }
138             set { primaryKeyName = value; }
139         }
140         
141         /// <summary>
142         /// 表实体描述信息
143         /// </summary>
144         public string Information
145         {
146             get { return information; }
147             set { information = value; }
148         }
149         
150         /// <summary>
151         /// 表实体是否国际化
152         /// </summary>
153         public bool IsInternal
154         {
155             get { return isInternal; }
156             set { isInternal = value; }
157         }
158         
159         /// <summary>
160         /// 表实体版本号
161         /// </summary>
162         public string Version
163         {
164             get { return version; }
165             set { version = value; }
166         }
167 
168         
169     }
170 }
171 

  特性说明:实体表特性,用于描述实体和数据库表之间的映射关系,该特性类使用 sealed 修改,说明该类不能够再被继承。

 

ColumnAttribute特性

字段名

作用

name

表字段名称,该属性的值最好与数据表的字段的名称相同。

该字段的值有两种格式:

(1) [表名].[字段名]

(2) [字段名]

如果该字段的值为(1)情况,则应分割字符串,将字段名

赋值给name属性,表名则赋值给tableName

tableName

表字段对应表名称

该值是可以为空的,如果name的值的情况满足(1)情况,

可以分割的值赋值给该属性

dataType

表字段的数据类型

该属性的类型为自定义类型,该字段是一个枚举类型。

该字段描述了25中数据类型

length

表字段的长度

控制该字段对应的数据库表字段值的最大长度

可以不指定该值

canNull

表字段是否可以为空

true 可以为空

false 不能为空

defaultValue

表字段的默认值

默认情况为null

isPrimaryKey

表字段是否为主键

true  为主键

false 不是外键

autoIncrement

表字段是否为自动增长列

true  是自动增长列

false 不是自动增长列

isUnique

确定某个字段是否唯一

true  是唯一的

false 不是唯一

regularExpress

表字段的匹配规则

字段匹配规则正则表达式

isForeignKey

表字段是否为外键

true  为外键

false 不是外键

foreignTabName

表字段外键对应的表名称

如果isForeignKey true,则需要指定其值

information

表字段的描述信息

 

 

 特性源码:

   1 /**

  2  * 2010-1-28
  3  * 
  4  * 情 缘
  5  * 
  6  * 实体表特性,用于描述实体字段和数据库表字段之间的映射关系
  7  * 
  8  * 该特性类使用 sealed 修改,说明该类不能够再被继承。
  9  * 
 10  * */
 11 
 12 using System;
 13 
 14 namespace CommonData.Model.Core
 15 {
 16     public sealed class ColumnAttribute:Attribute
 17     {
 18         /// <summary>
 19         /// 表字段名称,该属性的值最好与数据表的字段的名称相同。
 20         /// 该字段的值有两种格式:
 21         /// (1) [表名].[字段名] 
 22         /// (2) [字段名]
 23         /// 如果该字段的值为(1)情况,则应分割字符串,将字段名
 24         /// 赋值给name属性,表名则赋值给tableName
 25         /// </summary>
 26         private string name;
 27 
 28         /// <summary>
 29         /// 表字段对应表名称
 30         /// 该值是可以为空的,如果name的值的情况满足(1)情况,
 31         /// 可以分割的值赋值给该属性
 32         /// </summary>
 33         private string tableName;
 34 
 35         /// <summary>
 36         /// 表字段的数据类型
 37         /// 该属性的类型为自定义类型,该字段是一个枚举类型。
 38         /// 该字段描述了25中数据类型
 39         /// </summary>
 40         private DataType dataType;
 41 
 42         /// <summary>
 43         /// 表字段的长度
 44         /// 控制该字段对应的数据库表字段值的最大长度
 45         /// 可以不指定该值
 46         /// </summary>
 47         private int length;
 48 
 49         /// <summary>
 50         /// 表字段是否可以为空
 51         /// true 可以为空
 52         /// false 不能为空
 53         /// </summary>
 54         private bool canNull;
 55 
 56         /// <summary>
 57         /// 表字段的默认值
 58         /// 默认情况为null
 59         /// </summary>
 60         private object defaultValue;
 61 
 62         /// <summary>
 63         /// 表字段是否为主键
 64         /// true  为主键
 65         /// false 不是外键
 66         /// </summary>
 67         private bool isPrimaryKey = false;
 68 
 69         /// <summary>
 70         /// 表字段是否为自动增长列
 71         /// true  是自动增长列
 72         /// false 不是自动增长列
 73         /// </summary>
 74         private bool autoIncrement = false;
 75 
 76         /// <summary>
 77         /// 确定某个字段是否唯一
 78         /// true  是唯一的
 79         /// false 不是唯一
 80         /// </summary>
 81         private bool isUnique;
 82 
 83         /// <summary>
 84         /// 表字段的匹配规则
 85         /// 字段匹配规则正则表达式
 86         /// </summary>
 87         private string regularExpress;
 88 
 89         /// <summary>
 90         /// 表字段是否为外键
 91         /// true  为外键
 92         /// false 不是外键
 93         /// </summary>
 94         private bool isForeignKey=false;
 95 
 96         /// <summary>
 97         /// 表字段外键对应的表名称
 98         /// 如果isForeignKey 为true,则需要指定其值
 99         /// </summary>
100         private string foreignTabName;
101 
102         /// <summary>
103         /// 表字段的描述信息
104         /// </summary>
105         private string information;
106 
107 
108         /// <summary>
109         /// 无参数构造方法
110         /// </summary>
111         public ColumnAttribute()
112         { 
113         }
114 
115         /// <summary>
116         /// 部分参数构造方法,构造该特性实例时
117         /// 初始化部分实体属性的值
118         /// </summary>
119         /// <param name="name">表字段名称</param>
120         /// <param name="dataType">表字段的数据类型</param>
121         /// <param name="isPrimaryKey">表字段是否为主键</param>
122         /// <param name="autoIncrement">表字段是否为自动增长列</param>
123         /// <param name="isUnique">确定某个字段是否唯一</param>
124         /// <param name="isForeignKey">表字段是否为外键</param>
125         /// <param name="foreignTabName">表字段外键对应的表名称</param>
126         public ColumnAttribute(string name,
127             DataType dataType,
128             bool isPrimaryKey,
129             bool autoIncrement,
130             bool isUnique,
131             bool isForeignKey,
132             string foreignTabName)
133         {
134             this.name = name;
135             this.dataType = dataType;
136             this.isPrimaryKey = isPrimaryKey;
137             this.autoIncrement = autoIncrement;
138             this.isUnique = isUnique;
139             this.isForeignKey = isForeignKey;
140             this.foreignTabName = foreignTabName;
141         }
142 
143         /// <summary>
144         /// 全部参数构造方法,构造该特性实例时
145         /// 初始化全部实体属性的值
146         /// </summary>
147         /// <param name="name">表字段名称</param>
148         /// <param name="tableName">表字段对应表名称</param>
149         /// <param name="dataType">表字段的数据类型</param>
150         /// <param name="length">表字段的长度</param>
151         /// <param name="canNull">表字段是否可以为空</param>
152         /// <param name="defaultValue">表字段的默认值</param>
153         /// <param name="isPrimaryKey">表字段是否为主键</param>
154         /// <param name="autoIncrement">表字段是否为自动增长列</param>
155         /// <param name="isUnique">确定某个字段是否唯一</param>
156         /// <param name="regularExpress">表字段的匹配规则</param>
157         /// <param name="isForeignKey">表字段是否为外键</param>
158         /// <param name="foreignTabName">表字段外键对应的表名称</param>
159         /// <param name="information">表字段的描述信息</param>
160         public ColumnAttribute(string name,
161             string tableName,
162             DataType dataType,
163             int length,
164             bool canNull,
165             object defaultValue,
166             bool isPrimaryKey,
167             bool autoIncrement,
168             bool isUnique,
169             string regularExpress,
170             bool isForeignKey,
171             string foreignTabName,
172             string information)
173         {
174             this.name = name;
175             this.tableName = tableName;
176             this.dataType = dataType;
177             this.length = length;
178             this.canNull = canNull;
179             this.defaultValue = defaultValue;
180             this.isPrimaryKey = isPrimaryKey;
181             this.autoIncrement = autoIncrement;
182             this.regularExpress = regularExpress;
183             this.isForeignKey = isForeignKey;
184             this.ForeignTabName = foreignTabName;
185             this.information = information;
186             this.isUnique = isUnique;
187         }
188 
189         /// <summary>
190         /// 表字段名称
191         /// </summary>
192         public string Name
193         {
194             get { return name; }
195             set { name = value; }
196         }
197         
198         /// <summary>
199         /// 表字段对应表名称
200         /// </summary>
201         public string TableName
202         {
203             get { return tableName; }
204             set { tableName = value; }
205         }
206         
207         /// <summary>
208         /// 表字段的数据类型
209         /// </summary>
210         public DataType DataType
211         {
212             get { return dataType; }
213             set { dataType = value; }
214         }
215         
216         /// <summary>
217         /// 表字段的长度
218         /// </summary>
219         public int Length
220         {
221             get { return length; }
222             set { length = value; }
223         }
224         
225         /// <summary>
226         /// 表字段是否可以为空
227         /// </summary>
228         public bool CanNull
229         {
230             get { return canNull; }
231             set { canNull = value; }
232         }
233         
234         /// <summary>
235         /// 表字段的默认值
236         /// </summary>
237         public object DefaultValue
238         {
239             get { return defaultValue; }
240             set { defaultValue = value; }
241         }
242         
243         /// <summary>
244         /// 表字段是否为主键
245         /// </summary>
246         public bool IsPrimaryKey
247         {
248             get { return isPrimaryKey; }
249             set { isPrimaryKey = value; }
250         }
251         
252         /// <summary>
253         /// 表字段是否为自动增长列
254         /// </summary>
255         public bool AutoIncrement
256         {
257             get { return autoIncrement; }
258             set { autoIncrement = value; }
259         }
260         
261         /// <summary>
262         /// 表字段的匹配规则
263         /// </summary>
264         public string RegularExpress
265         {
266             get { return regularExpress; }
267             set { regularExpress = value; }
268         }
269         
270         /// <summary>
271         /// 表字段是否为外键
272         /// </summary>
273         public bool IsForeignKey
274         {
275             get { return isForeignKey; }
276             set { isForeignKey = value; }
277         }
278         
279         /// <summary>
280         /// 表字段外键对应的表名称
281         /// </summary>
282         public string ForeignTabName
283         {
284             get { return foreignTabName; }
285             set { foreignTabName = value; }
286         }
287         
288         /// <summary>
289         /// 表字段的描述信息
290         /// </summary>
291         public string Information
292         {
293             get { return information; }
294             set { information = value; }
295         }
296 
297         /// <summary>
298         /// 确定某个字段是否唯一
299         /// </summary>
300         public bool IsUnique
301         {
302             get { return isUnique; }
303             set { isUnique = value; }
304         }
305     }
306 }
307 

  特性说明:实体表特性,用于描述实体字段和数据库表字段之间的映射关系,该特性类使用 sealed 修改,说明该类不能够再被继承。

 

LinkTableAttribute 特性

字段名

作用

name

该实体属性对应的数据库表名

sqlPrefix

该实体属性对应的数据库表名前缀

一般情况下没有太大意思

dataType

该实体属性对应的数据类型

可以通过发射获得类型

keyName

该实体对应的主键类型

(用数据的列名来表示,不要使用实体的属性来定义)

className

对应的实体的全路径类型

isLazy

对应的实体是否延长加载

 

 

 特性源码:

  1 /**

  2  * 2010-1-28
  3  * 
  4  * 情 缘
  5  * 
  6  * 实体属性特性,用于描述某个实体作为另外一个实体
  7  * 的一个属性字段的时候与数据库表之间的关系
  8  *
  9  * 这个实体特性类和其余的几个有区别,没有用sealed 
 10  * 修饰,因为这个特性是用于修饰实体属性的,而实体属
 11  * 性的集合也是一种特殊的属性,所以可以使用
 12  * LinkTablesAttribute 来继承该特性。两者在属性描述
 13  * 上基本没有太大的区别
 14  * 
 15  * */
 16 
 17 using System;
 18 
 19 
 20 namespace CommonData.Model.Core
 21 {
 22     public class LinkTableAttribute:Attribute
 23     {
 24         /// <summary>
 25         /// 该实体属性对应的数据库表名
 26         /// </summary>
 27         private string name;
 28 
 29         /// <summary>
 30         /// 该实体属性对应的数据库表名前缀
 31         /// 一般情况下没有太大意思
 32         /// </summary>
 33         private string sqlPrefix;
 34 
 35         /// <summary>
 36         /// 该实体属性对应的数据类型
 37         /// 可以通过发射获得类型
 38         /// </summary>
 39         private Type dataType;
 40 
 41         /// <summary>
 42         /// 该实体对应的主键类型
 43         /// (用数据的列名来表示,不要使用实体的属性来定义)
 44         /// </summary>
 45         private string keyName;
 46 
 47         /// <summary>
 48         /// 对应的实体的全路径类型
 49         /// </summary>
 50         private string className;
 51 
 52         /// <summary>
 53         /// 对应的实体是否延长加载
 54         /// </summary>
 55         private bool isLazy;
 56 
 57         /// <summary>
 58         /// 无参数构造方法
 59         /// </summary>
 60         public LinkTableAttribute()
 61         { 
 62         }
 63 
 64         /// <summary>
 65         /// 部分参数构造方法,构造该特性实例的时候
 66         /// 初始化部分属性
 67         /// </summary>
 68         /// <param name="name">该实体属性对应的数据库表名</param>
 69         /// <param name="dataType">该实体属性对应的数据类型</param>
 70         /// <param name="keyName">该实体对应的主键类型</param>
 71         /// <param name="className">对应的实体的全路径类型</param>
 72         public LinkTableAttribute(string name, Type dataType, string keyName, string className)
 73         {
 74             this.name = name;
 75             this.dataType = dataType;
 76             this.keyName = keyName;
 77             this.className = className;
 78         }
 79 
 80         /// <summary>
 81         /// 全参数构造方法,构造该特性实例的时候
 82         /// 初始化全部属性
 83         /// </summary>
 84         /// <param name="name">该实体属性对应的数据库表名</param>
 85         /// <param name="sqlPrefix">该实体属性对应的数据库表名前缀</param>
 86         /// <param name="dataType">该实体属性对应的数据类型</param>
 87         /// <param name="keyName">该实体对应的主键类型</param>
 88         /// <param name="className">对应的实体的全路径类型</param>
 89         public LinkTableAttribute(string name,string sqlPrefix, Type dataType, string keyName, string className)
 90         {
 91             this.name = name;
 92             this.sqlPrefix = sqlPrefix;
 93             this.dataType = dataType;
 94             this.keyName = keyName;
 95             this.className = className;
 96         }
 97 
 98         public string Name
 99         {
100             get { return name; }
101             set { name = value; }
102         }
103 
104         
105         public string SqlPrefix
106         {
107             get { return sqlPrefix; }
108             set { sqlPrefix = value; }
109         }
110 
111         
112         public Type DataType
113         {
114             get { return dataType; }
115             set { dataType = value; }
116         }
117 
118         
119         public string KeyName
120         {
121             get { return keyName; }
122             set { keyName = value; }
123         }
124 
125         
126         public string ClassName
127         {
128             get { return className; }
129             set { className = value; }
130         }
131 
132         public bool IsLazy
133         {
134             get { return isLazy; }
135             set { isLazy = value; }
136         }
137     }
138 }
139 

  特性说明:实体属性特性,用于描述某个实体作为另外一个实体的一个属性字段的时候与数据库表之间的关系.这个实体特性类和其余的几个有区别,没有用sealed 修饰,因为这个特性是用于修饰实体属性的,而实体属 性的集合也是一种特殊的属性,所以可以使用LinkTablesAttribute 来继承该特性。两者在属性描述上基本没有太大的区别

 

LinkTablesAttribute 特性

 特性源码:

代码

 1 /**
 2  * 2010-1-28
 3  * 
 4  * 情 缘
 5  * 
 6  * 实体集合属性特性,用于描述某个实体作为另外一个实体
 7  * 的一个集合属性的时候与数据库表之间的关系
 8  * 
 9  * 这个特性使用了 sealed 修饰,说明该特性类不能再被继
10  * 承。但是这个实体类不是在继承Attribute,而是继承
11  * LinkTableAttribute。因为这两者描述的属性具有相同的
12  * 特性。只需要让它继承LinkTableAttribute 保留父类的
13  * 属性就可以了。 LinkTablesAttribute,LinkTableAttribute
14  * 这两个特性类具有相同的属性,使用不同的类名只是为了
15  * 区分修饰的属性形态有所不同
16  * 
17  * */
18 
19 using System;
20 
21 namespace CommonData.Model.Core
22 {
23     public sealed class LinkTablesAttribute:LinkTableAttribute
24     {
25         /// <summary>
26         /// 无参数构造方法
27         /// </summary>
28         public LinkTablesAttribute()
29         {
30         }
31 
32         /// <summary>
33         /// 部分参数构造方法,构造该特性实例的时候,
34         /// 初始化部分属性,并且调用的是父类的构造
35         /// 方法
36         /// </summary>
37         /// <param name="name">该实体属性对应的数据库表名</param>
38         /// <param name="dataType">该实体属性对应的数据类型</param>
39         /// <param name="keyName">该实体对应的主键类型</param>
40         /// <param name="className">对应的实体的全路径类型</param>
41         public LinkTablesAttribute(string name, Type dataType, string keyName, string className)
42             : base(name,dataType,keyName,className)
43         { }
44 
45 
46         /// <summary>
47         /// 全参数构造方法,构造该特性实例的时候
48         /// 初始化全部属性 ,并且调用的是父类的构造
49         /// 方法
50         /// </summary>
51         /// <param name="name">该实体属性对应的数据库表名</param>
52         /// <param name="sqlPrefix">该实体属性对应的数据库表名前缀</param>
53         /// <param name="dataType">该实体属性对应的数据类型</param>
54         /// <param name="keyName">该实体对应的主键类型</param>
55         /// <param name="className">对应的实体的全路径类型</param>
56         public LinkTablesAttribute(string name, string sqlPrefix, Type dataType, string keyName, string className)
57             :base(name,sqlPrefix,dataType,keyName,className)
58         { 
59         
60         }
61     }
62 }
63 

 特性说明:实体集合属性特性,用于描述某个实体作为另外一个实体的一个集合属性的时候与数据库表之间的关系

这个特性使用了 sealed 修饰,说明该特性类不能再被继承。但是这个实体类不是在继承Attribute,而是继承LinkTableAttribute。 因为这两者描述的属性具有相同的特性。只需要让它继承LinkTableAttribute 保留父类的属性就可以了。 LinkTablesAttribute,LinkTableAttribute这两个特性类具有相同的属性,使用不同的类名只是为了区分修饰的属性形态有所不同

源码点击下载

(注: ORM涉及内容比较多,后续期待。本文只是一个开端,有兴趣的可以与本人探讨) 


作者:情缘
出处:http://www.cnblogs.com/qingyuan/
关于作者:从事仓库,生产软件方面的开发,在项目管理以及企业经营方面寻求发展之路
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
联系方式: 个人QQ  821865130 ; 仓储技术QQ群 88718955,142050808 ;
吉特仓储管理系统 开源地址: https://github.com/hechenqingyuan/gitwms