调用 :

  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. Linux输入子系统(一) _驱动编码

    输入设备都有共性:中断驱动+字符IO,基于分层的思想,Linux内核将这些设备的公有的部分提取出来,基于cdev提供接口,设计了输入子系统,所有使用输入子系统构建的设备都使用主设备号13,同时输入子系 ...

  2. c#访问数据库的两种方法以及事务的两种方法

    //2015/07/03 using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...

  3. HttpClient构造文件上传

    在项目中我们有时候需要使用到其他第三方的api,而有些api要求我们上传文件,search一下,下面将结果记录一下喽! 含义 ENCTYPE="multipart/form-data&quo ...

  4. 【安装eclipse, 配置java环境教程】 编写第一个java程序

    写java通常用eclipse编写,还有一款编辑器比较流行叫IJ.这里我们只说下eclipse编写java的前期工作. 在安装eclipse之前要下载java的sdk文件,即java SE:否则无法运 ...

  5. 【转】jqGrid学习之参数

    jqGrid参数 名称 类型 描述 默认值 可修改 url string 获取数据的地址 datatype string 从服务器端返回的数据类型,默认xml.可选类型:xml,local,json, ...

  6. web性能优化 来自《web全栈工程师的自我修养》

    最近在看<web全栈工程师的自我修养>一书,作者是来自腾讯的前端工程师.作者在做招聘前端的时候问应聘者web新能优化有什么了解和经验,应聘者思索后回答“在发布项目之前压缩css和 Java ...

  7. [前言] 实现一个Android电子书阅读APP

    大家好,我是小方,我将在接下来的几篇文章中从零实现一个网络小说阅读器,从安卓编程最基础的部分讲起,直至成功完成我们的应用,从新建一个项目开始,不断添加新的代码,添加新的界面,循序渐进,涵盖所有我们需要 ...

  8. 项目架构开发:数据访问层之Repository

    接上文 项目架构开发:数据访问层之Logger 本章我们继续IRepository开发,这个仓储与领域模式里边的仓储有区别,更像一个工具类,也就是有些园友说的“伪仓储”, 这个仓储只实现单表的CURD ...

  9. Python 引用、浅拷贝、深拷贝解析

    引用 Python是动态数据类型的语言,故在对变量进行赋值时是不用制定变量类型的. 或者说,你可以把变量赋值的过程,当作是贴一个标签,去引用该数据. 看下面的例子: In [54]: a=4 In [ ...

  10. 基于Spring Cloud和Netflix OSS 构建微服务-Part 1

    前一篇文章<微服务操作模型>中,我们定义了微服务使用的操作模型.这篇文章中,我们将开始使用Spring Cloud和Netflix OSS实现这一模型,包含核心部分:服务发现(Servic ...