公布一个 150 行左右的 ORM
2012-08-20 17:31
85 查看
今天,一个因为ORM的性能问题引发了一场血案,唉。。。
突然想起来几年前我写的一个小东西,放上来大家评论一下,有兴趣的可以测试一下性能,呵呵。
原理很简单,利用Lambda表达式树生成一个Delegate,然后缓存起来。不多说了,下面上代码:
[code]usingSystem.Collections.Generic;
[/code]
上面用到了一个全能转换方法,代码如下:
[code]privatestaticstringtypeIConvertibleFullName=typeof(IConvertible).FullName;
[/code]
再次欢迎大家品鉴。
突然想起来几年前我写的一个小东西,放上来大家评论一下,有兴趣的可以测试一下性能,呵呵。
原理很简单,利用Lambda表达式树生成一个Delegate,然后缓存起来。不多说了,下面上代码:
usingSystem;
[code]usingSystem.Collections.Generic;
usingSystem.Data;
usingSystem.Diagnostics;
usingSystem.Linq;
usingSystem.Linq.Expressions;
usingSystem.Reflection;
usingLenic.Extensions;
namespaceLenic.Data.Extensions
{
///<summary>
///IDataReader扩展方法集合
///</summary>
[DebuggerStepThrough]
publicstaticclassDataReaderExtensions
{
#regionPrivateMethods
privatestaticreadonlyDictionary<Type,Delegate>cache=newDictionary<Type,Delegate>();
privatestaticreadonlyobjectcacheLocker=newobject();
#endregion
#regionBusinessMethods
///<summary>
///返回指定字段的值,并执行ConvertTo函数转换。
///</summary>
///<typeparamname="T">返回值类型。</typeparam>
///<paramname="reader">一个实现了IDataReader接口的实例对象。</param>
///<paramname="name">要查找的字段的名称。</param>
///<returns>转换完毕的T类型的结果。</returns>
publicstaticTField<T>(thisIDataReaderreader,stringname)
{
returnreader[name].ConvertTo<T>(default(T),false);
}
///<summary>
///返回指定字段的值,并执行ConvertTo函数转换。
///</summary>
///<typeparamname="T">返回值类型。</typeparam>
///<paramname="reader">一个实现了IDataReader接口的实例对象。</param>
///<paramname="index">要查找的字段的索引。</param>
///<returns>转换完毕的T类型的结果。</returns>
publicstaticTField<T>(thisIDataReaderreader,intindex)
{
returnreader[index].ConvertTo<T>(default(T),false);
}
///<summary>
///解析当前IDataReader类型的实例对象并提取一个T类型的列表。
///</summary>
///<typeparamname="T">待解析的元素类型,该类型必须包含一个默认的构造函数。</typeparam>
///<paramname="reader">一个实现了IDataReader接口的实例对象。</param>
///<returns>一个T类型的列表。</returns>
publicstaticList<T>ToList<T>(thisIDataReaderreader)whereT:class,new()
{
returnFill<T>(reader,DynamicCreateEntity<T>()).ToList();
}
///<summary>
///解析当前IDataReader类型的实例对象并提取一个T类型的列表。
///</summary>
///<typeparamname="T">待解析的元素类型,该类型必须包含一个默认的构造函数。</typeparam>
///<paramname="reader">一个实现了IDataReader接口的实例对象。</param>
///<paramname="predicate">映射委托。</param>
///<returns>一个T类型的列表。</returns>
publicstaticList<T>ToList<T>(thisIDataReaderreader,Func<IDataReader,T>predicate)
whereT:class,new()
{
returnFill<T>(reader,predicate).ToList();
}
#endregion
#regionPrivateMethods
///<summary>
///创建一个构造函数委托。
///</summary>
///<typeparamname="T">构造目标类型。</typeparam>
///<returns>构造完毕的Func委托。</returns>
privatestaticFunc<IDataReader,T>DynamicCreateEntity<T>()whereT:class,new()
{
vartype=typeof(T);
if(cache.ContainsKey(type))
return(Func<IDataReader,T>)cache[type];
lock(cacheLocker)
{
if(cache.ContainsKey(type))
return(Func<IDataReader,T>)cache[type];
varresult=DynamicCreateEntityLogic<T>();
cache.Add(type,result);
returnresult;
}
}
///<summary>
///创建一个构造函数委托(逻辑实现)。
///</summary>
///<typeparamname="T">构造目标类型。</typeparam>
///<returns>构造完毕的Func委托。</returns>
privatestaticFunc<IDataReader,T>DynamicCreateEntityLogic<T>()whereT:class,new()
{
//Compilesadelegateoftheform(IDataReaderr)=>newT{Prop1=r.Field<Prop1Type>("Prop1"),...}
ParameterExpressionr=Expression.Parameter(typeof(IDataReader),"r");
//GetPropertiesofthepropertycanreadandwrite
varprops=typeof(T).GetProperties(BindingFlags.Public|BindingFlags.Instance)
.Where(p=>p.CanRead&&p.CanWrite)
.ToArray();
//Createpropertybindingsforallwritableproperties
List<MemberBinding>bindings=newList<MemberBinding>(props.Length);
//Getthebindingmethod
varmethod=typeof(DataReaderExtensions).GetMethods()
.First(p=>p.Name=="Field"&&
p.GetParameters().Length==2&&
p.GetParameters()[1].ParameterType==typeof(string));
foreach(PropertyInfopropertyin(typeof(T).GetProperties()))
{
//Createexpressionrepresentingr.Field<property.PropertyType>(property.Name)
MethodCallExpressionpropertyValue=Expression.Call(
method.MakeGenericMethod(property.PropertyType),
r,Expression.Constant(property.Name));
//Assignthepropertyvaluetopropertythroughamemberbinding
MemberBindingbinding=Expression.Bind(property,propertyValue);
bindings.Add(binding);
}
//Createtheinitializer,whichinstantiatesaninstanceofTandsetspropertyvalues
//usingthememberbindingswejustcreated
Expressioninitializer=Expression.MemberInit(Expression.New(typeof(T)),bindings);
//Createthelambdaexpression,whichrepresentsthecompletedelegate(r=>initializer)
Expression<Func<IDataReader,T>>lambda=Expression.Lambda<Func<IDataReader,T>>(initializer,r);
returnlambda.Compile();
}
///<summary>
///从一个IDataReader的实例对象中提取一个T类型的列表。
///</summary>
///<typeparamname="T">结果列表中的元素类型,该类型必须包含一个默认的构造函数。</typeparam>
///<paramname="reader">一个实现了IDataReader接口的实例对象。</param>
///<returns>一个T类型的列表。</returns>
privatestaticIEnumerable<T>Fill<T>(IDataReaderreader,Func<IDataReader,T>predicate)whereT:class,new()
{
while(reader.Read())
yieldreturnpredicate(reader);
}
#endregion
}
}
[/code]
上面用到了一个全能转换方法,代码如下:
#regionTypeConvertExtensions
[code]privatestaticstringtypeIConvertibleFullName=typeof(IConvertible).FullName;
///<summary>
///将当前实例对象类型转换为T类型.
///</summary>
///<typeparamname="T">目标类型.</typeparam>
///<paramname="obj">当前实例.</param>
///<returns>转换完成的T类型的一个实例对象.</returns>
publicstaticTConvertTo<T>(thisobjectobj)
{
returnConvertTo(obj,default(T));
}
///<summary>
///将当前实例对象类型转换为T类型.
///</summary>
///<typeparamname="T">目标类型.</typeparam>
///<paramname="obj">当前实例.</param>
///<paramname="defaultValue">转换失败时的返回值.</param>
///<returns>转换完成的T类型的一个实例对象.</returns>
publicstaticTConvertTo<T>(thisobjectobj,TdefaultValue)
{
if(obj!=null)
{
if(objisT)
return(T)obj;
varsourceType=obj.GetType();
vartargetType=typeof(T);
if(targetType.IsEnum)
return(T)Enum.Parse(targetType,obj.ToString(),true);
if(sourceType.GetInterface(typeIConvertibleFullName)!=null&&
targetType.GetInterface(typeIConvertibleFullName)!=null)
return(T)Convert.ChangeType(obj,targetType);
varconverter=TypeDescriptor.GetConverter(obj);
if(converter!=null&&converter.CanConvertTo(targetType))
return(T)converter.ConvertTo(obj,targetType);
converter=TypeDescriptor.GetConverter(targetType);
if(converter!=null&&converter.CanConvertFrom(sourceType))
return(T)converter.ConvertFrom(obj);
thrownewApplicationException("converterror.");
}
thrownewArgumentNullException("obj");
}
///<summary>
///将当前实例对象类型转换为T类型.
///</summary>
///<typeparamname="T">目标类型.</typeparam>
///<paramname="obj">当前实例.</param>
///<paramname="defaultValue">转换失败时的返回值.</param>
///<paramname="ignoreException">如果设置为<c>true</c>表示忽略异常信息,直接返回缺省值.</param>
///<returns>转换完成的T类型的一个实例对象.</returns>
publicstaticTConvertTo<T>(thisobjectobj,TdefaultValue,boolignoreException)
{
if(ignoreException)
{
try
{
returnobj.ConvertTo<T>(defaultValue);
}
catch
{
returndefaultValue;
}
}
returnobj.ConvertTo<T>(defaultValue);
}
#endregion
[/code]
再次欢迎大家品鉴。
相关文章推荐
- 网络抢票黄牛,大部分是骗人的。公布一个骗钱黄牛,QQ:2233261390,QQ群:29443597,支付页面:https://me.alipay.com/q336
- 中管高校应及时向社会公布巡视整改情况,接受干部群众监督,一个不能少!
- 公布一个IOS上线程安全的sqlite库
- Android之greenDao,一个orm的使用
- 编写Applet(大小140*60),其背景色为蓝色,画一个长方形(其填充色为pink色,各边离Applet的边为10像素)和一个在填充的长方形中左右移动的小球(半径15)。
- 做一个悬浮的div和左右两边的广告
- 设置一个DIV固定在底部,并且左右固定,垂直居中
- 一个javascript的左右滚动切换效果!javascript
- 现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。给定一个地图map及它的长宽n和m,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。
- Hibernate是一个开放源代码的对象关系映射框架(ORM)
- 实现一个简单的按钮实例-上下左右,左旋转,右旋转,放大缩小。
- 把页面分成左右两个,如何实现在左侧点击,链接一个页面到右边的页面
- Daject初探 - 一个开源关系型数据库对象关系映射(ORM)模型
- 负边距(negative margin)实现自适应的div左右排版(一个宽度固定一个宽度自适应)”
- 公布一年前发现阿里旺旺的一个xss漏洞的细节。
- WPF-19:分享一个样式(左右滑动选中的checbox)
- WPF-19:分享一个样式(左右滑动选中的checbox)
- 一个用C#的ORM小框架
- 算法习题45:对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一;;;一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 公布一个PPT0day