您的位置:首页 > 其它

公布一个 150 行左右的 ORM

2012-08-20 17:31 85 查看
今天,一个因为ORM的性能问题引发了一场血案,唉。。。

突然想起来几年前我写的一个小东西,放上来大家评论一下,有兴趣的可以测试一下性能,呵呵。

原理很简单,利用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]

再次欢迎大家品鉴。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐