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

 

原理很简单,利用 Lambda 表达式树生成一个 Delegate ,然后缓存起来。不多说了,下面上代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Lenic.Extensions;
 
namespace Lenic.Data.Extensions
{
///
/// IDataReader 扩展方法集合
///
[DebuggerStepThrough]
public static class DataReaderExtensions
{
#region Private Methods
private static readonly Dictionary cache = new Dictionary();
private static readonly object cacheLocker = new object();
#endregion
 
#region Business Methods
///
/// 返回指定字段的值, 并执行 ConvertTo 函数转换。
///
/// 返回值类型。
/// 一个实现了 IDataReader 接口的实例对象。
/// 要查找的字段的名称。
/// 转换完毕的 T 类型的结果。
public static T Field(this IDataReader reader, string name)
{
return reader[name].ConvertTo(default(T), false);
}
 
///
/// 返回指定字段的值, 并执行 ConvertTo 函数转换。
///
/// 返回值类型。
/// 一个实现了 IDataReader 接口的实例对象。
/// 要查找的字段的索引。
/// 转换完毕的 T 类型的结果。
public static T Field(this IDataReader reader, int index)
{
return reader[index].ConvertTo(default(T), false);
}
 
///
/// 解析当前 IDataReader 类型的实例对象并提取一个 T 类型的列表。
///
/// 待解析的元素类型, 该类型必须包含一个默认的构造函数。
/// 一个实现了 IDataReader 接口的实例对象。
/// 一个 T 类型的列表。
public static List ToList(this IDataReader reader) where T : classnew()
{
return Fill(reader, DynamicCreateEntity()).ToList();
}
 
///
/// 解析当前 IDataReader 类型的实例对象并提取一个 T 类型的列表。
///
/// 待解析的元素类型, 该类型必须包含一个默认的构造函数。
/// 一个实现了 IDataReader 接口的实例对象。
/// 映射委托。
/// 一个 T 类型的列表。
public static List ToList(this IDataReader reader, Func predicate)
where T : classnew()
{
return Fill(reader, predicate).ToList();
}
#endregion
 
#region Private Methods
///
/// 创建一个 构造函数 委托。
///
/// 构造目标类型。
/// 构造完毕的 Func 委托。
private static Func DynamicCreateEntity() where T : classnew()
{
var type = typeof(T);
if (cache.ContainsKey(type))
return (Func)cache[type];
 
lock (cacheLocker)
{
if (cache.ContainsKey(type))
return (Func)cache[type];
 
var result = DynamicCreateEntityLogic();
cache.Add(type, result);
return result;
}
}
 
///
/// 创建一个 构造函数 委托(逻辑实现)。
///
/// 构造目标类型。
/// 构造完毕的 Func 委托。
private static Func DynamicCreateEntityLogic() where T : classnew()
{
ParameterExpression r = Expression.Parameter(typeof(IDataReader), "r");
 
// Get Properties of the property can read and write
var props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead && p.CanWrite)
.ToArray();
 
// Create property bindings for all writable properties
List bindings = new List(props.Length);
 
// Get the binding method
var method = typeof(DataReaderExtensions).GetMethods()
.First(p => p.Name == "Field" &&
p.GetParameters().Length == 2 &&
p.GetParameters()[1].ParameterType == typeof(string));
 
foreach (PropertyInfo property in (typeof(T).GetProperties()))
{
// Create expression representing r.Field(property.Name)
MethodCallExpression propertyValue = Expression.Call(
method.MakeGenericMethod(property.PropertyType),
r, Expression.Constant(property.Name));
 
// Assign the property value to property through a member binding
MemberBinding binding = Expression.Bind(property, propertyValue);
bindings.Add(binding);
}
 
// using the member bindings we just created
 
 
return lambda.Compile();
}
 
///
/// 从一个 IDataReader 的实例对象中提取一个 T 类型的列表。
///
/// 结果列表中的元素类型, 该类型必须包含一个默认的构造函数。
/// 一个实现了 IDataReader 接口的实例对象。
/// 一个 T 类型的列表。
{
while (reader.Read())
yield return predicate(reader);
}
#endregion
}
}

 

 

再次欢迎大家品鉴。java 培训