Farseer.net轻量级开源框架 中级篇:探究ORM(Mapping)
上一篇: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来完成执行数据库操作的。
Mapping.cs :映射的核心文件,都是通过该类,来完成对实体与数据库之间的映射过程。
ModelCache.cs :映射缓存,致使我们不需要对实体进行重复的反射操作。将会在第一次映射后缓存起来。
DBAttribute.cs :顾名思义,是数据库的特性。比如前面我们看到在实体类名称的特征:[DB(Name="xxx表名称",DbIndex = 1)]
ModelAttribute.cs :这个是属性字段的映射,包括字段的名称、中文名称、必填、长度、自增列等。
这个对象将会对实体类的表信息、字段信息(多个)进行全面解析。
/// <summary>
/// ORM 映射关系
/// </summary>
public class Mapping
{
/// <summary>
/// 获取所有属性
/// </summary>
public readonly Dictionary<PropertyInfo, ModelAttribute> ModelList; /// <summary>
/// 关系映射
/// </summary>
/// <param name="type">实体类Type</param>
internal Mapping(Type type) /// <summary>
/// 类属性
/// </summary>
public DBAttribute ClassInfo { get; set; } /// <summary>
/// 自增ID
/// </summary>
public string IndexName { get; set; } /// <summary>
/// 类型
/// </summary>
public Type Type { get; set; } /// <summary>
/// 通过实体类型,返回Mapping
/// </summary>
public static implicit operator Mapping(Type type) /// <summary>
/// 获取当前属性(通过使用的propertyName)
/// </summary>
/// <param name="propertyName">属性名称</param>
public KeyValuePair<PropertyInfo, ModelAttribute> GetModelInfo(string propertyName = "") /// <summary>
/// 获取标注的名称
/// </summary>
/// <param name="propertyInfo">属性变量</param>
/// <returns></returns>
public string GetUserName(PropertyInfo propertyInfo)
}
Mapping的构造函数传入的是实体类的Type。然后对这个类进行 《类特性》、《属性特性》的转化。同时因为这里涉及到数据库类型及访问方式了,所以Db.Config如果不存在,则会创建这份配置文件出来。
同时加入对数据验证的错误提示:
// 字符串长度判断
if (modelAtt.StringLength != null && modelAtt.StringLength.ErrorMessage.IsNullOrEmpty())
{
if (modelAtt.StringLength.MinimumLength > && modelAtt.StringLength.MaximumLength > )
{
modelAtt.StringLength.ErrorMessage = string.Format("{0},长度范围必需为:{1} - {2} 个字符之间!", modelAtt.Display.Name, modelAtt.StringLength.MinimumLength, modelAtt.StringLength.MaximumLength);
}
else if (modelAtt.StringLength.MaximumLength > )
{
modelAtt.StringLength.ErrorMessage = string.Format("{0},长度不能大于{1}个字符!", modelAtt.Display.Name, modelAtt.StringLength.MaximumLength);
}
else
{
modelAtt.StringLength.ErrorMessage = string.Format("{0},长度不能小于{1}个字符!", modelAtt.Display.Name, modelAtt.StringLength.MinimumLength);
}
} // 值的长度
if (modelAtt.Range != null && modelAtt.Range.ErrorMessage.IsNullOrEmpty())
{
if (modelAtt.Range.Minimum.ConvertType(0m) > && modelAtt.Range.Maximum.ConvertType(0m) > )
{
modelAtt.Range.ErrorMessage = string.Format("{0},的值范围必需为:{1} - {2} 之间!", modelAtt.Display.Name, modelAtt.Range.Minimum.ConvertType(0m), modelAtt.Range.Maximum.ConvertType(0m));
}
else if (modelAtt.Range.Maximum.ConvertType(0m) > )
{
modelAtt.Range.ErrorMessage = string.Format("{0},的值不能大于{1}!", modelAtt.Display.Name, modelAtt.Range.Maximum.ConvertType(0m));
}
else
{
modelAtt.Range.ErrorMessage = string.Format("{0},的值不能小于{1}!", modelAtt.Display.Name, modelAtt.Range.Minimum.ConvertType(0m));
}
}
通过ModelList,我们可以获取该类的所有字段信息。这对我们在一些项目执行的过程中需要动态的获取类属性的信息是很有需要的。
GetModelInfo,通过传入数据库字段名称,找到映射的类属性。
GetFieldName,通过传入类属性,找到映射的数据库字段信息。
namespace FS.ORM
{
/// <summary>
/// 缓存数据库和实体类的映射关系
/// </summary>
public static class ModelCache
{
/// <summary>
/// 缓存所有实体类
/// </summary>
private static readonly Dictionary<Type, Mapping> ModelList = new Dictionary<Type, Mapping>(); private static readonly object LockObject = new object(); /// <summary>
/// 返回实体类映射的信息
/// </summary>
/// <param name="type">实体类Type</param>
public static Mapping GetInfo(Type type)
{
if (!ModelList.ContainsKey(type))
{
lock (LockObject)
{
if (!ModelList.ContainsKey(type))
{
ModelList.Add(type, new Mapping(type));
}
}
} return ModelList[type];
} /// <summary>
/// 清除缓存
/// </summary>
public static void ClearCache()
{
ModelList.Clear();
}
}
}
ModelCache对象就是将Mapping进行缓存的操作。通过GetInfo方法,进行缓存并返回Mapping对象。
因此大家如果需要Mapping对象时,必须通过ModelCache.GetInfo的静态方法进行获取。否则直接操作Mapping对象,将会引发性能问题。
存储与数据库的类型、访问方式,及表名称。
/// <summary>
/// 实体类的属性标记
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class DBAttribute : Attribute
{
/// <summary>
/// 表名
/// </summary>
public string Name { get; set; } /// <summary>
/// 设置数据库连接配置(Dbconfig)的索引项
/// </summary>
public int DbIndex { get; set; } /// <summary>
/// 设置数据库连接字符串
/// </summary>
public string ConnStr { get; set; } /// <summary>
/// 设置数据库类型
/// </summary>
public DataBaseType DataType { get; set; } /// <summary>
/// 设置数据库版本
/// </summary>
public string DataVer { get; set; } /// <summary>
/// 设置数据库执行T-SQL时间,单位秒默认是30秒
/// </summary>
public int CommandTimeout { get; set; }
这里代码比较少,我就不在贴上来了,大家可以到框架中查看。大部份的特性,我们还是利用LINQ TO SQL的。可以减少大家的学习成本。
主要是针对字段的必填、数据长度、数字值类型的范围、或者正则(可自定义加入如邮件格式、手机格式的验证)。
另外需要说明的是,默认所有字段都是映射到数据库字段的。如果有一些额外的字段不想加入到字段中。
可以在字段的特性申明:[NotJoinAttribute(true)],表明该类属性不对数据库的字段进行映射。
上一篇:Farseer.net轻量级开源框架 中级篇: SQL执行报告
下一篇:Farseer.net轻量级开源框架 中级篇: Cookies、Session、Request
QQ群:116228666 (Farseer.net开源框架交流) 请注明:Farseer.Net
Farseer.Net是一款ORM框架 + 常用工具 + 扩展集合。
Farseer 意为:先知、预言家 通常在某些场合时,提供计谋、策略。也希望该框架能给大家提供最大化的便捷。
ORM:其英文全称是:Object(对象) Relational(关系) Mapping(映射)
Farseer.Net的目标是:快速上手、快速开发、简单方便。
new User { ID = , Name = "张三" }.Insert()
Farseer.net轻量级开源框架 中级篇:探究ORM(Mapping)的更多相关文章
- Farseer.net轻量级开源框架 中级篇:Cookies、Session、Request
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 探究ORM(Mapping) 下一篇:Farseer.net轻量级开源框架 中级篇 ...
- Farseer.net轻量级开源框架 中级篇:SQL执行报告
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 数据库切换 下一篇:Farseer.net轻量级开源框架 中级篇: 探究ORM(M ...
- Farseer.net轻量级开源框架 中级篇:UrlRewriter 地址重写
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: Cookies.Session.Request 下一篇:Farseer.net轻量 ...
- Farseer.net轻量级开源框架 中级篇:常用的扩展方法
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: BasePage.BaseController.BaseHandler.BaseM ...
- Farseer.net轻量级开源框架 中级篇:BasePage、BaseController、BaseHandler、BaseMasterPage、BaseControls基类使用
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: UrlRewriter 地址重写 下一篇:Farseer.net轻量级开源框架 中 ...
- Farseer.net轻量级开源框架 中级篇:事务的使用
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: Where条件的终极使用 下一篇:Farseer.net轻量级开源框架 中级篇: ...
- Farseer.net轻量级开源框架 中级篇:执行SQL语句
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 事务的使用 下一篇:Farseer.net轻量级开源框架 中级篇: DbFacto ...
- Farseer.net轻量级开源框架 中级篇:DbFactory数据工厂
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: 执行SQL语句 下一篇:Farseer.net轻量级开源框架 中级篇: 数据绑定 ...
- Farseer.net轻量级开源框架 中级篇:数据绑定
导航 目 录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: DbFactory数据工厂 下一篇:Farseer.net轻量级开源框架 中级篇: ...
随机推荐
- 2016/3/31 ①全选时 下面选项全选中 ② 下面不选中时 全选取消 ③在“” 中 转义字符的使用\ onclick=\"Checkpa(this,'flall')\"; ④区别于分别实现 重点在于两种情况合并实现
testxuanbuxuan.php <!DOCTYPE html> <html lang="en"> <head> <meta char ...
- Adding Security to an Existing Website
The procedure earlier in this article relies on using the Starter Site template as the basis for web ...
- YTU 2440: C++习题 复数类--重载运算符+,-,*,/
2440: C++习题 复数类--重载运算符+,-,*,/ 时间限制: 1 Sec 内存限制: 128 MB 提交: 1189 解决: 774 题目描述 定义一个复数类Complex,重载运算符& ...
- Masonry整体动画更新约束
前言 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自动布局,也有人使用frame来适配.对于前者,笔者并不喜欢,也不支持.对于后者,更是麻烦,到处计算高度.宽度等,千万 ...
- 并不对劲的bzoj3832: [Poi2014]Rally
传送门-> 这题的原理看上去很神奇. 称拓扑图中入度为0的点为“起点”,出度为0的点为“终点”. 因为“起点”和“终点”可能有很多个,算起来会很麻烦,所以新建“超级起点”S,向所有点连边,“超级 ...
- [Codeforces 839C] Journey
[题目链接] http://codeforces.com/contest/839/problem/C [算法] 概率DP 时间复杂度 : O(N) [代码] #include<bits/stdc ...
- BZOJ 4815 数论
今年的重庆省选? 具体就是,对于每次修改,A[p,q]这个位置, 设d=gcd(p,q) ,则 gcd为d的每一个格子都会被修改,且他们之间有个不变的联系 A[p,q]/p/q==A[k,t]/k/ ...
- AutoIT: 捕捉路由器登陆的小例子
$url2 = "AX.XXX.XXX.COM" $oIE = _IECreate ($url2, , , , ) Sleep() ControlSetText('[REGEXPT ...
- ZOJ5593:Let's Chat(双指针)
传送门 题意 给出x个a区间和y个b区间,询问a和b交区间的子区间长度为m的个数 分析 类似于双指针,具体见代码 trick 代码 #include <bits/stdc++.h> usi ...
- HDU1254:推箱子(bfs+dfs)
传送门 题意 给出一副图 0.空地1.墙2.箱子3.目的地4.人所在的位置 问最少几步能将箱子推到目的地 分析 这道题难度略大(菜鸡),首先用vis[bx][by][mx][my]记录当箱子(bx,b ...