调用 :

  public ActionResult Index()
{
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");
dt.Columns.Add("RegisterTime123");
dt.Columns.Add("Last123LoginTime");
dt.Columns.Add("Active");
dt.Rows.Add("zs0", , DateTime.Now.AddDays(-), DateTime.Now, );
dt.Rows.Add("zs1", , DateTime.Now.AddDays(-), DateTime.Now, );
dt.Rows.Add("zs2", , DateTime.Now.AddDays(-), DateTime.Now, );
dt.Rows.Add("zs3", , DateTime.Now.AddDays(-), DateTime.Now, );
dt.Rows.Add("zs4", , DateTime.Now.AddDays(-), DateTime.Now, );
List<People> list = new List<People>(); //1、 不定义映射时,默认会转换属性名和列名相同的列,属性名和列名不区分大小写
list = DataToModelHelper.RefDataTableToList<People>(dt); //2、 添加自定义列名和属性名映射 默认列名和属性名相同的也会转换
ColumnPropertyMapping[] cmMaps = {
new ColumnPropertyMapping("Last123LoginTime","lastLoginTime")
,new ColumnPropertyMapping("RegisterTime123","registerTime")
};
list = DataToModelHelper.RefDataTableToList<People>(dt, cmMaps); //
//3、 DataReader 转换
string sql =
@" select userid Cuserid, username Cusername, passwordhash Cpasswordhash,
email, phonenumber, isfirsttimelogin, accessfailedcount, creationdate, isactive from cicuser ";
List<CICUser> list = null;
ColumnPropertyMapping[] cpmaps = {
new ColumnPropertyMapping("Cuserid", "userid")
,new ColumnPropertyMapping("Cusername", "username")
,new ColumnPropertyMapping("Cpasswordhash", "passwordhash")
};
using (IDataReader reader = OHelper.ExecuteReader(sql))
{
list = DataToModelHelper.RefDataReaderToList<CICUser>(reader); // 默认匹配和属性名相同的列
list = DataToModelHelper.RefDataReaderToList<CICUser>(reader,cpmaps); // 优先匹配自定义映射
} return View();
}

测试实体:

  // 测试的实体类
public class People
{
public string name { get; set; }
public int age { get; set; }
public DateTime registerTime { get; set; }
public DateTime lastLoginTime { get; set; }
public int active { get; set; }
}

Helper :

 using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace xxoo.Common
{ /** 反射实现DataTable To Model **/
// 实体转换类
public class DataToModelHelper
{ private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> TypeProperties = new ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>>(); private static IEnumerable<PropertyInfo> TypePropertiesCache(Type type)
{
IEnumerable<PropertyInfo> pis;
if (TypeProperties.TryGetValue(type.TypeHandle, out pis))
{
return pis;
} var properties = type.GetProperties();
TypeProperties[type.TypeHandle] = properties;
return properties;
} /// <summary>
/// 通过反射实体属性名称 将DataTable转换实体集
/// 列名和属性名称不区分大小写
/// </summary>
/// <typeparam name="T">需要转换的实体类型</typeparam>
/// <param name="ds">查询的数据表</param>
/// <param name="parMaps">自定义的实体属性和DataTable列名的映射</param>
/// <returns>实体集合</returns>
public static List<T> RefDataTableToList<T>(DataTable ds, params ColumnPropertyMapping[] parMaps) where T : new()
{ List<T> list = new List<T>();
if (ds == null || ds.Rows.Count <= )
return list; // 没有数据 List<ColumnPropertyConvert<T>> rmmpList = new List<ColumnPropertyConvert<T>>(); //实体列映射集合
List<string> columnNameList = new List<string>();
// 循环获取到实体属性
foreach (DataColumn item in ds.Columns)
{ //列名转换为小写
columnNameList.Add(item.ColumnName.ToLower());
} var type = typeof(T);
var allProperties = TypePropertiesCache(type); // 读取缓存属性 if (parMaps == null || parMaps.Length == )
{ //无自定义映射,默认查找列名和属性名相同的映射
foreach (System.Reflection.PropertyInfo proInfo in allProperties)
{ // 循环实体属性集合
if (columnNameList.Contains(proInfo.Name.ToLower()))
{ //列明中包含该属性名称
ColumnPropertyConvert<T> map = new ColumnPropertyConvert<T>(proInfo.Name, proInfo.Name, proInfo);
// 判断是否是可空类型
if (proInfo.PropertyType.IsGenericType && proInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
map.isNullable = true;
}
rmmpList.Add(map);
}
}
}
else
{ //有自定义映射,查找默认映射同时 查找自定义映射 foreach (System.Reflection.PropertyInfo proInfo in allProperties)
{ // 循环实体属性集合
if (columnNameList.Contains(proInfo.Name.ToLower()))
{ //列明中包含该属性名称
ColumnPropertyConvert<T> map = new ColumnPropertyConvert<T>(proInfo.Name, proInfo.Name, proInfo);
// 判断是否是可空类型
if (proInfo.PropertyType.IsGenericType && proInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
map.isNullable = true;
}
rmmpList.Add(map);
}
else
{
foreach (ColumnPropertyMapping parMap in parMaps)
{
// 存在该属性 和 该列
if (parMap.ProertyName.ToLower() == proInfo.Name.ToLower() && columnNameList.Contains(parMap.ColumnName.ToLower()))
{
ColumnPropertyConvert<T> map = new ColumnPropertyConvert<T>(parMap.ColumnName, proInfo.Name, proInfo); //列名用反射得到的准确
// 判断是否是可空类型
if (proInfo.PropertyType.IsGenericType && proInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
map.isNullable = true;
}
rmmpList.Add(map);
}
}
}
}
} if (rmmpList.Count == ) return list; // 没有列名和属性名的映射 // 装载实体数据
foreach (DataRow row in ds.Rows)
{
T t = new T();
foreach (ColumnPropertyConvert<T> map in rmmpList)
{
try
{
map.ParseValue(t, map.ProInfo, row[map.ColumnName]);
}
catch { continue; }
} list.Add(t);
}//foreach datarow
return list;
} /// <summary>
/// 通过反射实体属性名称 将DataTable转换实体集
/// 列名和属性名称不区分大小写
/// </summary>
/// <typeparam name="T">需要转换的实体类型</typeparam>
/// <param name="ds">查询的数据表</param>
/// <param name="parMaps">自定义的实体属性和DataReader列名的映射</param>
/// <returns>实体集合</returns>
public static List<T> RefDataReaderToList<T>(IDataReader dr, params ColumnPropertyMapping[] parMaps) where T : new()
{ List<T> list = new List<T>();
if (dr == null)
return list; // 没有数据 List<ColumnPropertyConvert<T>> rmmpList = new List<ColumnPropertyConvert<T>>(); //实体列映射集合
List<string> columnNameList = new List<string>();
int fieldCount = dr.FieldCount;
for (int i = ; i < fieldCount; i++)
{
columnNameList.Add(dr.GetName(i).ToLower());
} #region 配置实体属性和列名映射
var type = typeof(T);
var allProperties = TypePropertiesCache(type); // 读取缓存属性 if (parMaps == null || parMaps.Length == )
{ //无自定义映射,默认查找列名和属性名相同的映射
foreach (System.Reflection.PropertyInfo proInfo in allProperties)
{ // 循环实体属性集合
if (columnNameList.Contains(proInfo.Name.ToLower()))
{ //列明中包含该属性名称
ColumnPropertyConvert<T> map = new ColumnPropertyConvert<T>(proInfo.Name, proInfo.Name, proInfo);
// 判断是否是可空类型
if (proInfo.PropertyType.IsGenericType && proInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
map.isNullable = true;
rmmpList.Add(map);
}
}
}
else
{ //有自定义映射,查找默认映射同时 查找自定义映射 foreach (System.Reflection.PropertyInfo proInfo in allProperties)
{ // 循环实体属性集合
if (columnNameList.Contains(proInfo.Name.ToLower()))
{ //列明中包含该属性名称
ColumnPropertyConvert<T> map = new ColumnPropertyConvert<T>(proInfo.Name, proInfo.Name, proInfo);
// 判断是否是可空类型
if (proInfo.PropertyType.IsGenericType && proInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
map.isNullable = true;
rmmpList.Add(map);
}
else
{
foreach (ColumnPropertyMapping parMap in parMaps)
{
// 存在该属性 和 该列
if (parMap.ProertyName.ToLower() == proInfo.Name.ToLower() && columnNameList.Contains(parMap.ColumnName.ToLower()))
{
ColumnPropertyConvert<T> map = new ColumnPropertyConvert<T>(parMap.ColumnName, proInfo.Name, proInfo); //列名用反射得到的准确
// 判断是否是可空类型
if (proInfo.PropertyType.IsGenericType && proInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
map.isNullable = true;
rmmpList.Add(map);
}
}
}
}
}
#endregion if (rmmpList.Count == ) return list; // 没有列名和属性名的映射 // 装载实体数据
while (dr.Read())
{
T t = new T();
foreach (ColumnPropertyConvert<T> map in rmmpList)
{
try
{
map.ParseValue(t, map.ProInfo, dr[map.ColumnName]);
}
catch { continue; }
} list.Add(t);
}
dr.Close();
dr.Dispose(); return list;
} }
/// <summary>
/// 自定义映射类
/// </summary>
public class ColumnPropertyMapping
{
/// <summary>
/// 列名与实体属性名的映射
/// </summary>
/// <param name="columnName">列名</param>
/// <param name="proertyName">属性名称</param>
public ColumnPropertyMapping(string columnName, string proertyName)
{
this.ColumnName = columnName;
this.ProertyName = proertyName;
}
public string ColumnName { get; set; }
public string ProertyName { get; set; }
}
/// <summary>
/// 属性列名数据转换器器
/// </summary>
/// <typeparam name="T"></typeparam>
public class ColumnPropertyConvert<T> where T : new()
{
public ColumnPropertyConvert(string columnName, string proertyName, System.Reflection.PropertyInfo proInfo)
{
this.ColumnName = columnName;
this.ProertyName = proertyName;
this.ProInfo = proInfo;
isNullable = false; this.ParseValue = (t, m, o) =>
{ if (!isNullable)
{
this.ProInfo.SetValue(t, Convert.ChangeType(o, this.ProInfo.PropertyType), null);
}
else { // 可空类型
this.ProInfo.SetValue(t, Convert.ChangeType(o, Nullable.GetUnderlyingType(m.PropertyType)), null);
}
};
#region 注释
//switch (this.ProInfo.PropertyType.ToString())
//{
// case "System.Int32":
// this.ParseValue = (t, m, o) =>
// { // this.ProInfo.SetValue(t, int.Parse(o.ToString()), null);
// };
// break;
// case "System.Boolean":
// this.ParseValue = (t, m, o) =>
// {
// this.ProInfo.SetValue(t, bool.Parse(o.ToString()), null);
// };
// break;
// case "System.String":
// this.ParseValue = (t, m, o) =>
// {
// this.ProInfo.SetValue(t, o.ToString(), null);
// };
// break;
// case "System.DateTime":
// this.ParseValue = (t, m, o) =>
// {
// this.ProInfo.SetValue(t, DateTime.Parse(o.ToString()), null);
// };
// break;
// case "System.Decimal":
// this.ParseValue = (t, m, o) =>
// {
// this.ProInfo.SetValue(t, decimal.Parse(o.ToString()), null);
// };
// break;
// case "System.Guid":
// this.ParseValue = (t, m, o) =>
// {
// this.ProInfo.SetValue(t, Guid.Parse(o.ToString()), null);
// };
// break;
// default:
// break;
//}//swicth
#endregion
} public bool isNullable { get; set; }
public string ColumnName { get; set; }
public string ProertyName { get; set; }
public System.Reflection.PropertyInfo ProInfo { get; set; }
// "System.Int32":"System.Boolean":"System.String":"System.DateTime":"System.Decimal":"System.Guid": public Action<T, System.Reflection.PropertyInfo, object> ParseValue;
}
}

反射实现 Data To Model的更多相关文章

  1. 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model

    利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model   使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...

  2. 利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理

    利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理   2018-3-10 15:18 | 发布:Admin | 分类:代码库 | 评论: ...

  3. 在整合spring和mongodb中,提示at org.springframework.data.mapping.model.BasicPersistentEntity.findAnnotation(

    遇到这种坑,找了好多资料.基本是都是因为springdata的jar包和spring的版本不兼容导致,除了这个错误之外,还有会比较多其他错误,也是版本不兼容导致的. at org.springfram ...

  4. elasticsearch6.7 05. Document APIs(1)data replication model

    data replication model 本节首先简要介绍Elasticsearch的data replication model,然后详细描述以下CRUD api: 1.读写文档(Reading ...

  5. 运用模型绑定和web窗体显示和检索数据(Retrieving and displaying data with model binding and web forms)

    原文 http://www.asp.net/web-forms/overview/presenting-and-managing-data/model-binding/retrieving-data ...

  6. C# 反射之SqlDatareader转换为Model实体.

    虽说反射的效率比较低,但是在当今的时代,盛行的大数据,以及高并发的产生,硬件的产能正在逐渐的提升,所以我们可以用空间来换取时间.反射所消耗的那些性能问题其实在企业级开发而言也就无所谓了.二 : 反射得 ...

  7. Metadata file not found - Data.Entity.Model

    错误 3 正在编译转换: 未能找到元数据文件“F:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\..\IDE\Micr ...

  8. C# 利用反射动态给模型Model 赋值

    https://www.cnblogs.com/waitingfor/articles/2220669.html object ff = Activator.CreateInstance(tt, nu ...

  9. ExtJS笔记 Ext.data.Model

    A Model represents some object that your application manages. For example, one might define a Model ...

随机推荐

  1. Java静态代理和动态代理总结

    静态代理 第一种实现(基于接口): 1>接口 public interface Hello { void say(String msg);} 2>目标类,至少实现一个接口 public c ...

  2. PhotoshopCC 如何使用动作文件ATN

    非常感谢公司的前端同事,今早给我推荐了一个很好用的插件 atn ,下面简单的总结下 导入 atn 插件的方法: 打开 photoshop 或者 photoshopCC 软件→点击 窗口菜单→找到 动作 ...

  3. "ORA-01460: 转换请求无法实现或不合理"及C#操作Blob总结

    class BlobDemo { private static readonly string ConnectionString = "Data Source=Tcco;User ID=sc ...

  4. js拉起或下载app

    产品提了个需求,通过手机网页判断是否安装了自己公司app,如果安装了则拉起app,没有安装则跳转到下载页. 经过各种查阅资料尝试总结了一个还算可以的办法. 拉起app的原理就是js和原生统一好一个地址 ...

  5. MYSQL中添加时间

    1.在创建新记录和修改现有记录的时候都对这个数据列刷新:TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 2.在创建新记录 ...

  6. 用Less定义常用的CSS3效果函数及常用颜色搭配(让CSS写起来更有趣)

    定义圆角及调用 /* 定义圆角 @radius 圆角大小 */ .round(@radius:5px){ border-radius:@radius; -webkit-border-radius: @ ...

  7. spring源码浅析——IOC

    =========================================== 原文链接: spring源码浅析--IOC   转载请注明出处! ======================= ...

  8. 手把手教你webpack、react和node.js环境配置(下篇)

    上篇我介绍了前端下webpack和react.redux等环境的配置,这篇将继续重点介绍后台node.js的配置. 这里是上篇链接:手把手教你webpack.react和node.js环境配置(上篇) ...

  9. w7如何安装配置多个tomcat

    最近工作比较闲,所以我就开始做自己的项目.公司的的项目用的是tomcat7 为了和公司的项目区分开,我打算再配置一个tomcat.问题也就随之而至.经过整理之后,我整理出了一个完整的流程.保证可以在w ...

  10. Python拉勾爬虫——以深圳地区数据分析师为例

    拉勾因其结构化的数据比较多因此过去常常被爬,所以在其多次改版之下变得难爬.不过只要清楚它的原理,依然比较好爬.其机制主要就是AJAX异步加载JSON数据,所以至少在搜索页面里翻页url不会变化,而且数 ...