using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Demo1
{
public
static
class
EntityConverter
{
#region
public
static
List<T> ToList<T>(
this
DataTable dataTable) where T :
class
,
new
()
{
if
(dataTable ==
null
|| dataTable.Rows.Count <=
0
)
throw
new
ArgumentNullException(
"dataTable"
,
"当前对象为null无法生成表达式树"
);
Func<DataRow, T> func = dataTable.Rows[
0
].ToExpression<T>();
List<T> collection =
new
List<T>(dataTable.Rows.Count);
foreach (DataRow dr in dataTable.Rows)
{
collection.Add(func(dr));
}
return
collection;
}
public
static
Func<DataRow, T> ToExpression<T>(
this
DataRow dataRow) where T :
class
,
new
()
{
if
(dataRow ==
null
)
throw
new
ArgumentNullException(
"dataRow"
,
"当前对象为null 无法转换成实体"
);
ParameterExpression parameter = Expression.Parameter(typeof(DataRow),
"dr"
);
List<MemberBinding> binds =
new
List<MemberBinding>();
for
(
int
i =
0
; i < dataRow.ItemArray.Length; i++)
{
String colName = dataRow.Table.Columns[i].ColumnName;
PropertyInfo pInfo = typeof(T).GetProperty(colName);
if
(pInfo ==
null
|| !pInfo.CanWrite)
continue
;
MethodInfo mInfo = typeof(DataRowExtensions).GetMethod(
"Field"
,
new
Type[] { typeof(DataRow), typeof(String) }).MakeGenericMethod(pInfo.PropertyType);
MethodCallExpression call = Expression.Call(mInfo, parameter, Expression.Constant(colName, typeof(String)));
MemberAssignment bind = Expression.Bind(pInfo, call);
binds.Add(bind);
}
MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
return
Expression.Lambda<Func<DataRow, T>>(init, parameter).Compile();
}
#endregion
public
static
Func<SqlDataReader, T> ToExpression<T>(
this
SqlDataReader reader) where T :
class
,
new
()
{
if
(reader ==
null
|| reader.IsClosed || !reader.HasRows)
throw
new
ArgumentException(
"reader"
,
"当前对象无效"
);
ParameterExpression parameter = Expression.Parameter(typeof(SqlDataReader),
"reader"
);
List<MemberBinding> binds =
new
List<MemberBinding>();
for
(
int
i =
0
; i < reader.FieldCount; i++)
{
String colName = reader.GetName(i);
PropertyInfo pInfo = typeof(T).GetProperty(colName);
if
(pInfo ==
null
|| !pInfo.CanWrite)
continue
;
MethodInfo mInfo = reader.GetType().GetMethod(
"GetFieldValue"
).MakeGenericMethod(pInfo.PropertyType);
MethodCallExpression call = Expression.Call(parameter, mInfo, Expression.Constant(i));
MemberAssignment bind = Expression.Bind(pInfo, call);
binds.Add(bind);
}
MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
return
Expression.Lambda<Func<SqlDataReader, T>>(init, parameter).Compile();
}
}
}