前言
最近在捣鼓DataTable,弄到了类型转换,既然弄了,那就整个记录。有不足之处,请多多指教。我看了一下目前的转换方式基本上都大差不差,基本上都是通过反射来操作的。本文介绍的两种方式也都是利用反射来完成的。两种方式都写成的通用类,仅供参考。
想法
DataTable
DataTable 是 C# 中常用的一种数据表格类型,它类似于数据库中的表格,可以用来存储和处理数据。DataTable 中的数据可以通过行和列来访问和操作,每行代表一个数据项,每列代表一个属性。
以下是一些 DataTable 的常用属性和方法:
-
Columns
:列集合。 -
Rows
:行集合。 -
NewRow()
:创建一个新的 DataRow 对象。 -
Load(DataReader)
:从一个 DataReader 对象中加载数据到 DataTable。 -
Select(filterExpression, sortExpression)
:根据指定的筛选条件和排序条件返回满足条件的行集合。 -
Merge(DataTable)
:合并两个 DataTable,返回一个新的 DataTable。
List
List 是 C# 中常用的一种动态数组类型,它可以用来存储任何类型的数据,可以动态增加或删除元素。List 中的元素可以通过索引来访问和操作。
以下是一些 List 的常用属性和方法:
-
Count
:元素数量。 -
Add(item)
:添加一个元素到 List 的末尾。 -
Insert(index, item)
:在指定的位置插入一个元素。 -
Remove(item)
:从 List 中删除一个元素。 -
RemoveAt(index)
:删除指定位置的元素。 -
Contains(item)
:判断 List 中是否包含指定的元素。
完整代码
方式一
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Data; using System.Reflection; namespace GCT.TestInterface { public static class DataTableHelper { /// <summary> /// DataTable转成List /// </summary> public static List<T> ToDataList<T>(this DataTable dt) { var list = new List<T>(); //创建一个属性的列表,并赋值 var plist = new List<PropertyInfo>(typeof(T).GetProperties()); if (dt == null || dt.Rows.Count == 0) { return null; } foreach (DataRow item in dt.Rows) { //实例化泛型对象 T s = Activator.CreateInstance<T>(); //遍历dataTable中的列集合 for (int i = 0; i < dt.Columns.Count; i++) { //获取属性和DataTable的列名称相同的属性(PropertyInfo) PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName); //判断是否存在 if (info != null) { try { //判断是否为空 if (!Convert.IsDBNull(item[i])) { object v = null; //判断属性是否包含可空 if (info.PropertyType.ToString().Contains("System.Nullable")) { //类型转换 v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType)); } else { //类型转换 v = Convert.ChangeType(item[i], info.PropertyType); } //赋值 info.SetValue(s, v, null); } } catch (Exception ex) { throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message); } } } list.Add(s); } return list; } /// <summary> /// DataTable转成实体对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dt"></param> /// <returns></returns> public static T ToDataEntity<T>(this DataTable dt) { T s = Activator.CreateInstance<T>(); if (dt == null || dt.Rows.Count == 0) { return default(T); } var plist = new List<PropertyInfo>(typeof(T).GetProperties()); for (int i = 0; i < dt.Columns.Count; i++) { PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName); if (info != null) { try { if (!Convert.IsDBNull(dt.Rows[0][i])) { object v = null; if (info.PropertyType.ToString().Contains("System.Nullable")) { v = Convert.ChangeType(dt.Rows[0][i], Nullable.GetUnderlyingType(info.PropertyType)); } else { v = Convert.ChangeType(dt.Rows[0][i], info.PropertyType); } info.SetValue(s, v, null); } } catch (Exception ex) { throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message); } } } return s; } /// <summary> /// List转成DataTable /// </summary> /// <typeparam name="T">实体类型</typeparam> /// <param name="entities">实体集合</param> public static DataTable ToDataTable<T>(List<T> entities) { //判断List的状态 if (entities == null || entities.Count == 0) { return null; } //新建一个DataTable var result = new DataTable(); //获取实体类型数据 var type = typeof(T); //遍历实体类型数据 foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { //获取属性类型 var propertyType = property.PropertyType; //判断是否存在,是否可为空 if (propertyType.IsGenericType && (propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))) { propertyType = propertyType.GetGenericArguments()[0]; } //添加列 result.Columns.Add(property.Name, propertyType); } foreach (var entity in entities) { //创建一个具有相同架构的表格行 DataRow row = result.NewRow(); foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { //填充数据 row[property.Name] = property.GetValue(entity) ?? DBNull.Value; } //添加行 result.Rows.Add(row); } return result; } } }
方式二
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Data; using System.Reflection; namespace GCT.TestInterface { public static class DataTableHelper { /// <summary> /// 利用反射将Datatable转换为List<T>对象 /// </summary> /// <typeparam name="T">集合</typeparam> /// <param name="dt"> datatable对象</param> /// <returns></returns> public static List<T> ToDataList<T>(this DataTable dt) where T : new() { //定义集合 List<T> ts = new List<T>(); //遍历dataTable中的数据行 foreach (DataRow dr in dt.Rows) { T t = new T(); //这里也有两种写法,可以先获取模型的属性数组,也先遍历再获取指定值的属性,看自己喜好采用 #region 获得此模型的公共属性 获得此模型的公共属性 PropertyInfo[] propertys = t.GetType().GetProperties(); //遍历该对象的所有属性 foreach (PropertyInfo pi in propertys) { string tempName = pi.Name; //检查datatable是否包含此列(列名==对象的属性名) //判断此属性是否有setter,这个啥意思呢,就是我们的实体层的{get;set;}如果我们的实体有了set方法,就说明可以赋值! if (!dt.Columns.Contains(tempName) && !pi.CanWrite) continue; object value = dr[tempName];//取值 if (value == DBNull.Value) continue; //如果非空,则赋给对象的属性 pi.SetValue(t, ConvertHelper.HackType(value, pi.PropertyType), null); } #endregion #region 先遍历再获取指定的 //遍历dataTable列集合 foreach (var c in dt.Columns) { //读取值 object value = dr[c.ToString()]; //判断是否存在 if (value != DBNull.Value) { //获取指定值的属性 var p = t.GetType().GetProperty(c.ToString()); if (p != null) { //对象赋值 p.SetValue(t, ConvertHelper.ChangeType(value, p.PropertyType), null); } } } #endregion //对象添加到泛型集合中 ts.Add(t); } return ts; } /// <summary> /// DataTable转成实体对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dt"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public static T ToDataEntity<T>(this DataTable dt) where T : new() { if (dt.Rows.Count > 1) { throw new Exception(""); } //遍历行 foreach (DataRow dr in dt.Rows) { T t = new T(); //遍历列 foreach (var c in dt.Columns) { //获取指定值 object value = dr[c.ToString()]; if (value != DBNull.Value) { //获取公共属性 var p = t.GetType().GetProperty(c.ToString()); if (p != null) { p.SetValue(t, ConvertHelper.ChangeType(value, p.PropertyType), null); } } } return t; } return default(T); } } }
-
类型转换
用方式二有时候会报类型转换的错误,因此也提供了两种转换方式
/// <summary> /// 类型转换 /// </summary> public static class ConvertHelper { #region 方式一 public static object HackType(object value, Type conversionType) { if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { if (value == null) return null; System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(conversionType); conversionType = nullableConverter.UnderlyingType; } return Convert.ChangeType(value, conversionType); } #endregion 方式一 #region 方式二 public static object ChangeType(object obj, Type conversionType) { return ChangeType(obj, conversionType, System.Threading.Thread.CurrentThread.CurrentCulture); } public static object ChangeType(object obj, Type conversionType, IFormatProvider provider) { #region Nullable Type nullableType = Nullable.GetUnderlyingType(conversionType); if (nullableType != null) { if (obj == null) { return null; } return Convert.ChangeType(obj, nullableType, provider); } #endregion Nullable if (typeof(Enum).IsAssignableFrom(conversionType)) { return Enum.Parse(conversionType, obj.ToString()); } return Convert.ChangeType(obj, conversionType, provider); } #endregion 方式二 }
方法三
// 将 DataTable 转换为 List public static List<Dictionary<string, object>> DataTableToList(DataTable dt) { List<Dictionary<string, object>> list = new List<Dictionary<string, object>>(); foreach (DataRow row in dt.Rows) { Dictionary<string, object> dict = new Dictionary<string, object>(); foreach (DataColumn col in dt.Columns) { dict[col.ColumnName] = row[col]; } list.Add(dict); } return list; } // 将 List 转换为 DataTable public static DataTable ListToDataTable(List<Dictionary<string, object>> list) { DataTable dt = new DataTable(); if (list.Count > 0) { foreach (string columnName in list[0].Keys) { dt.Columns.Add(columnName); } } foreach (Dictionary<string, object> dict in list) { DataRow row = dt.NewRow(); foreach (string columnName in dict.Keys) { row[columnName] = dict[columnName]; } dt.Rows.Add(row); } return dt; }
这里的
DataTableToList
方法将 DataTable 转换为一个 List,其中每个元素都是一个 Dictionary,表示 DataTable 的一行数据。每个 Dictionary 的键是 DataTable 的列名,值是该行对应列的值。文章来源:https://www.toymoban.com/news/detail-427765.html
ListToDataTable
方法则将 List 转换为 DataTable,需要注意的是,List 中的每个元素都必须具有相同的键集合,否则无法创建 DataTable。文章来源地址https://www.toymoban.com/news/detail-427765.html
到了这里,关于C# DataTable和List之间相互转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!