Farseer.net轻量级开源框架 中级篇:探究ORM(Mapping)

导航

目   录:Farseer.net轻量级开源框架 目录

上一篇:Farseer.net轻量级开源框架 中级篇: SQL执行报告

下一篇:Farseer.net轻量级开源框架 中级篇: Cookies、Session、Request

  在Farseer.Net 中 ORM的核心在命名空间:FS.ORM 。

  目前只有4个类文件。其实这4个文件只要是用来做数据库与实体模型之间的映射关系及缓存。至于SQL生成、不同数据库的驱动支持等 在另外的命名空间:FS.Core 中。

  对于ORM来说,我们在转换成数据库操作前,是先让Farseer.Net能“读懂”实体与数据库之间的关系,才能做出对应的SQL生成操作。在本框架中,实际都是最终生成SQL。交由ADO.NET来完成执行数据库操作的。

4个类文件的说明

  Mapping.cs    :映射的核心文件,都是通过该类,来完成对实体与数据库之间的映射过程。

  ModelCache.cs   :映射缓存,致使我们不需要对实体进行重复的反射操作。将会在第一次映射后缓存起来。

  DBAttribute.cs   :顾名思义,是数据库的特性。比如前面我们看到在实体类名称的特征:[DB(Name="xxx表名称",DbIndex = 1)]

  ModelAttribute.cs   :这个是属性字段的映射,包括字段的名称、中文名称、必填、长度、自增列等。

Mapping

  这个对象将会对实体类的表信息、字段信息(多个)进行全面解析。

 1     /// <summary>
 2     ///     ORM 映射关系
 3     /// </summary>
 4     public class Mapping
 5     {
 6         /// <summary>
 7         ///     获取所有属性
 8         /// </summary>
 9         public readonly Dictionary<PropertyInfo, ModelAttribute> ModelList;
10
11         /// <summary>
12         ///     关系映射
13         /// </summary>
14         /// <param name="type">实体类Type</param>
15         internal Mapping(Type type)
16
17         /// <summary>
18         ///     类属性
19         /// </summary>
20         public DBAttribute ClassInfo { get; set; }
21
22         /// <summary>
23         ///     自增ID
24         /// </summary>
25         public string IndexName { get; set; }
26
27         /// <summary>
28         ///     类型
29         /// </summary>
30         public Type Type { get; set; }
31
32         /// <summary>
33         ///     通过实体类型,返回Mapping
34         /// </summary>
35         public static implicit operator Mapping(Type type)
36
37         /// <summary>
38         ///     获取当前属性(通过使用的propertyName)
39         /// </summary>
40         /// <param name="propertyName">属性名称</param>
41         public KeyValuePair<PropertyInfo, ModelAttribute> GetModelInfo(string propertyName = "")
42
43         /// <summary>
44         ///     获取标注的名称
45         /// </summary>
46         /// <param name="propertyInfo">属性变量</param>
47         /// <returns></returns>
48         public string GetUserName(PropertyInfo propertyInfo)
49     }

  Mapping的构造函数传入的是实体类的Type。然后对这个类进行 《类特性》、《属性特性》的转化。同时因为这里涉及到数据库类型及访问方式了,所以Db.Config如果不存在,则会创建这份配置文件出来。

  同时加入对数据验证的错误提示:

 1                 // 字符串长度判断
 2                 if (modelAtt.StringLength != null && modelAtt.StringLength.ErrorMessage.IsNullOrEmpty())
 3                 {
 4                     if (modelAtt.StringLength.MinimumLength > 0 && modelAtt.StringLength.MaximumLength > 0)
 5                     {
 6                         modelAtt.StringLength.ErrorMessage = string.Format("{0},长度范围必需为:{1} - {2} 个字符之间!", modelAtt.Display.Name, modelAtt.StringLength.MinimumLength, modelAtt.StringLength.MaximumLength);
 7                     }
 8                     else if (modelAtt.StringLength.MaximumLength > 0)
 9                     {
10                         modelAtt.StringLength.ErrorMessage = string.Format("{0},长度不能大于{1}个字符!", modelAtt.Display.Name, modelAtt.StringLength.MaximumLength);
11                     }
12                     else
13                     {
14                         modelAtt.StringLength.ErrorMessage = string.Format("{0},长度不能小于{1}个字符!", modelAtt.Display.Name, modelAtt.StringLength.MinimumLength);
15                     }
16                 }
17
18                 // 值的长度
19                 if (modelAtt.Range != null && modelAtt.Range.ErrorMessage.IsNullOrEmpty())
20                 {
21                     if (modelAtt.Range.Minimum.ConvertType(0m) > 0 && modelAtt.Range.Maximum.ConvertType(0m) > 0)
22                     {
23                         modelAtt.Range.ErrorMessage = string.Format("{0},的值范围必需为:{1} - {2} 之间!", modelAtt.Display.Name, modelAtt.Range.Minimum.ConvertType(0m), modelAtt.Range.Maximum.ConvertType(0m));
24                     }
25                     else if (modelAtt.Range.Maximum.ConvertType(0m) > 0)
26                     {
27                         modelAtt.Range.ErrorMessage = string.Format("{0},的值不能大于{1}!", modelAtt.Display.Name, modelAtt.Range.Maximum.ConvertType(0m));
28                     }
29                     else
30                     {
31                         modelAtt.Range.ErrorMessage = string.Format("{0},的值不能小于{1}!", modelAtt.Display.Name, modelAtt.Range.Minimum.ConvertType(0m));
32                     }
33                 }

  通过ModelList,我们可以获取该类的所有字段信息。这对我们在一些项目执行的过程中需要动态的获取类属性的信息是很有需要的。

  GetModelInfo,通过传入数据库字段名称,找到映射的类属性。

  GetFieldName,通过传入类属性,找到映射的数据库字段信息。

ModelCache

 1 namespace FS.ORM
 2 {
 3     /// <summary>
 4     ///     缓存数据库和实体类的映射关系
 5     /// </summary>
 6     public static class ModelCache
 7     {
 8         /// <summary>
 9         ///     缓存所有实体类
10         /// </summary>
11         private static readonly Dictionary<Type, Mapping> ModelList = new Dictionary<Type, Mapping>();
12
13         private static readonly object LockObject = new object();
14
15         /// <summary>
16         ///     返回实体类映射的信息
17         /// </summary>
18         /// <param name="type">实体类Type</param>
19         public static Mapping GetInfo(Type type)
20         {
21             if (!ModelList.ContainsKey(type))
22             {
23                 lock (LockObject)
24                 {
25                     if (!ModelList.ContainsKey(type))
26                     {
27                         ModelList.Add(type, new Mapping(type));
28                     }
29                 }
30             }
31
32             return ModelList[type];
33         }
34
35         /// <summary>
36         ///     清除缓存
37         /// </summary>
38         public static void ClearCache()
39         {
40             ModelList.Clear();
41         }
42     }
43 }

  ModelCache对象就是将Mapping进行缓存的操作。通过GetInfo方法,进行缓存并返回Mapping对象。

  因此大家如果需要Mapping对象时,必须通过ModelCache.GetInfo的静态方法进行获取。否则直接操作Mapping对象,将会引发性能问题。

DBAttribute

  存储与数据库的类型、访问方式,及表名称。

 1     /// <summary>
 2     ///     实体类的属性标记
 3     /// </summary>
 4     [AttributeUsage(AttributeTargets.Class)]
 5     public sealed class DBAttribute : Attribute
 6     {
 7         /// <summary>
 8         ///     表名
 9         /// </summary>
10         public string Name { get; set; }
11
12         /// <summary>
13         ///     设置数据库连接配置(Dbconfig)的索引项
14         /// </summary>
15         public int DbIndex { get; set; }
16
17         /// <summary>
18         ///     设置数据库连接字符串
19         /// </summary>
20         public string ConnStr { get; set; }
21
22         /// <summary>
23         ///     设置数据库类型
24         /// </summary>
25         public DataBaseType DataType { get; set; }
26
27         /// <summary>
28         ///     设置数据库版本
29         /// </summary>
30         public string DataVer { get; set; }
31
32         /// <summary>
33         ///     设置数据库执行T-SQL时间,单位秒默认是30秒
34         /// </summary>
35         public int CommandTimeout { get; set; }

ModelAttribute

  这里代码比较少,我就不在贴上来了,大家可以到框架中查看。大部份的特性,我们还是利用LINQ TO SQL的。可以减少大家的学习成本。

  主要是针对字段的必填、数据长度、数字值类型的范围、或者正则(可自定义加入如邮件格式、手机格式的验证)。

  另外需要说明的是,默认所有字段都是映射到数据库字段的。如果有一些额外的字段不想加入到字段中。

  可以在字段的特性申明:[NotJoinAttribute(true)],表明该类属性不对数据库的字段进行映射。

导航

目   录:Farseer.net轻量级开源框架 目录

上一篇:Farseer.net轻量级开源框架 中级篇: SQL执行报告

下一篇:Farseer.net轻量级开源框架 中级篇: Cookies、Session、Request

广告时间

QQ群:116228666 (Farseer.net开源框架交流) 请注明:博客园

Farseer.Net是一款ORM框架 + 常用工具 + 扩展集合。

Farseer 意为:先知、预言家 通常在某些场合时,提供计谋、策略。也希望该框架能给大家提供最大化的便捷。

ORM:其英文全称是:Object(对象) Relational(关系) Mapping(映射)

Farseer.Net的目标是:快速上手、快速开发、简单方便。

1 new User { ID = 1, Name = "张三" }.Insert()
时间: 2024-10-10 17:36:09

Farseer.net轻量级开源框架 中级篇:探究ORM(Mapping)的相关文章

Farseer.net轻量级开源框架 中级篇:SQL执行报告

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 数据库切换 下一篇:Farseer.net轻量级开源框架 中级篇: 探究ORM(Mapping) 很多时候,我们希望能知道我们写的项目在运行过程中到底执行了哪些SQL语句,或者说一个页面中访问了几次数据库.好让我们在优化的时候提供一些方向. 举个例子,作者在有时候,会自信的认为这个页面很简单,估计也就顶多5条SQL语句就可以了.可是当打开SQL报告之后才吓傻眼,几十条SQL,看的

Farseer.net轻量级开源框架 中级篇:Cookies、Session、Request

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 探究ORM(Mapping) 下一篇:Farseer.net轻量级开源框架 中级篇: UrlRewriter 地址重写 Cookies.Session.Request是专门针对WEB项目的额外支持. 顺便说下,今天有园友在群里问到ORM对MVC的支持.或者对WinForm支持吗?对于ORM来说,本身是对表现层没有任何的联系.它仅仅是让你在开发的时候,能以面向对象的思想(语法)去做

Farseer.net轻量级开源框架 中级篇:数据库切换

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 动态数据库访问 下一篇:Farseer.net轻量级开源框架 中级篇: SQL执行报告 上文中讲述了,在项目运行过程中,如何通过代码动态改变数据库的访问,这种方式更加倾向于实体类相同,有多个相同的表结构. 本篇中讲述的是,如何快速切换不同的数据库.比如你现在使用在使用SqlServer 哪天数据库老板心血来潮,让你换成Oracle了,怎么办? 这种数据库的切换在ORM中能明显突出

Farseer.net轻量级开源框架 中级篇:动态数据库访问

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 自定义配置文件 下一篇:Farseer.net轻量级开源框架 中级篇: 数据库切换 说到动态数据库的访问,不得不说的是,我们的实体类,是如何找到数据库配置并访问的呢? 回顾下我们的Users类: 1 [DB(Name = "Members_User")] 2 public class Users : BaseModel<Users>; 这里有个DB的特性,其

Farseer.net轻量级开源框架 中级篇:常用的扩展方法

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: BasePage.BaseController.BaseHandler.BaseMasterPage.BaseControls基类使用 下一篇:Farseer.net轻量级开源框架 中级篇: 常用工具 在使用框架的时候,都需要引用扩展方法的命名空间:using FS.Extend; 1 /// <summary> 2 /// 将值转换成类型对像的值(此方法作为公共的调用,只支持

Farseer.net轻量级开源框架 中级篇:自定义配置文件

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 数据绑定 下一篇:Farseer.net轻量级开源框架 中级篇: 动态数据库访问 什么是自定义配置文件 目前系统提供了多个配置文件,一些开发过程中常用到的一些配置. 既然是配置,那么说明一些设置可能会根据项目的不同而有所不同.比如web.config其实就是个配置文件. 当我们定义好配置文件后,在项目运行的时调用了配置,都将在:~/App_Data/  文件夹中生成(如果不存在这

Farseer.net轻量级开源框架 中级篇:BasePage、BaseController、BaseHandler、BaseMasterPage、BaseControls基类使用

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: UrlRewriter 地址重写 下一篇:Farseer.net轻量级开源框架 中级篇: 常用的扩展方法 BasePage基类:  在Asp.Net中我们建立的aspx页面都是继承在:System.Web.UI.Page.在使用Farseer后,需要继承到:FS.Core.Page.BasePage中. BaseController基类: 在Asp.Net中我们建立的mvc控制器

Farseer.net轻量级开源框架 中级篇:DbFactory数据工厂

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 执行SQL语句 下一篇:Farseer.net轻量级开源框架 中级篇: 数据绑定 越讲到后面,我们离基础的语法越远了.看到这篇文章,先恭喜下,说明大家已经能用该框架做日常的开发了. 当然还有一些绑定技巧,比如把枚举.List<Users>绑定到DorpDownList.CheckBoxList.RadioButtonList 并显示中文 在下一篇中再解释. 这一篇中,我们主要讲

Farseer.net轻量级开源框架 中级篇:UrlRewriter 地址重写

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: Cookies.Session.Request 下一篇:Farseer.net轻量级开源框架 中级篇: BasePage.BaseController.BaseHandler.BaseMasterPage基类说明 MVC有路由在手,对于重写URL那是小菜一碟,更或者说是与身就有的“技能”,而面对.Net的WebForm就比较尴尬了.对UrlRewriter处在相对比较薄弱的环节.