C# DataTable和List之间相互转换

这篇具有很好参考价值的文章主要介绍了C# DataTable和List之间相互转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近在捣鼓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 的列名,值是该行对应列的值。

ListToDataTable 方法则将 List 转换为 DataTable,需要注意的是,List 中的每个元素都必须具有相同的键集合,否则无法创建 DataTable。文章来源地址https://www.toymoban.com/news/detail-427765.html

到了这里,关于C# DataTable和List之间相互转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中 List 和 JSON字符串之间的相互转换

    Java中 List 和 JSON字符串之间的相互转换 List 转 JSON 字符串 前端js将后端的json字符串转对象 JSON字符串转List

    2024年04月23日
    浏览(73)
  • Java:List相互转换数组

    经常我们会遇到前端传服务端值为数组的时候我们需要对其转换成集合便于一些其它操作,删除,匹配等操作,今天我们就总结下数组集合相互转换的方法 1、Object[] objArray = arrayList.toArray(); 2、String[] strArray = new String[list.size()]; 3、String[] strArray = list.toArray(new String[list.size()])

    2024年01月18日
    浏览(47)
  • Java实体和JSON之间的相互转换

    代码如下: 初始化并输出一下: 注意,如果没有使用“@Data”注解,一定要加上get和set方法,不然转化之后的Json是空的! 主要是对SerializerFeature枚举类的使用,详细的可以看这个博客: https://blog.csdn.net/xiang__liu/article/details/81570923 或者看这里: https://www.javadoc.io/static/com.ali

    2024年02月12日
    浏览(49)
  • java byte数组与int之间相互转换

    运算符 含义 说明 与 对应位都是1,结果为1,否则为0 | 或 对应位都是0,结果为0,否则为1 ~ 取反 每一位变相反位,即0变成1,1变成0 ^ 异或 对应位值相同,结果为0,否则为1 左移位 低位补0 右移位 保留符号位,0为正,1为负 无符号右移位 高位补0 位逻辑运算示例 A B AB A|B

    2024年04月14日
    浏览(60)
  • java中日期转换Date、DateTime、TimeStamp、String之间相互转换

    1.1Date-String 2.1Date-TimeStamp 2.2TimeStamp-Date DateTime使用依赖 3.1Date-DateTime 方法1: 方法2: 3.2DateTime-Date 4.String转DateTime

    2024年02月15日
    浏览(58)
  • Java 中图片与二进制之间如何相互转换?

    1、 下面是一个完整的代码示例。 指定文件路径转为二进制 将网络图片转为二进制 base64 转为图片资源 2、如何判断 base64 图片的格式? 3、将网络图片转为 base64 字符串 4、将 base64 字符串转为图片输出 注:该方法的入参,base64 格式文件不得有 文件头部标识信息,否则会转换

    2024年02月10日
    浏览(48)
  • Json对象和Json字符串之间相互转换

    作为前端开发,在和后端进行联调接口时,总会遇到要求传JSON字符串或是JSON对象,或者是返回值里是JSON字符串要在页面上展示JSON对象这种情况,都需要前端开发人员对Json对象和Json对象进行相互转换,得到想要的结果。 废话不多说,直接上干货: 1.首先定义一个Json对象:

    2024年02月11日
    浏览(59)
  • 无缝数据转换!使用C++ 实现 Excel文件与CSV之间的相互转换

    CSV格式是一种通用的文本文件格式,可在多个应用程序之间共享和使用。相比之下,Excel文件是一种电子表格格式,通常只能在Microsoft Excel中编辑和查看。因此,将Excel文件转换为CSV格式可使数据更方便地在其他应用程序中使用;而将CSV文件转换为Excel格式则有利于在Microsoft

    2024年02月11日
    浏览(36)
  • js实现base64,url,blob之间的相互转换

    一般来说前端展示图片会通过三种方式: url、base64、blob 1.url: 一般来说,图片的显示还是建议使用url的方式比较好。 2.base64: 如果图片较大,图片的色彩层次比较丰富,则不适合使用这种方式,因为其Base64编码后的字符串非常大,会明显增大HTML页面,影响加载速度。如果图

    2023年04月27日
    浏览(53)
  • 【Python】数据框DataFrame和列表List相互转换

    在使用一些别人封装好的库的时候,调用函数返回的结果便是DataFrame,这时如果要对内部数据做一些加工处理的话会很不方便。我们要需要将DataFrame还原成列表的形式来处理。     列表转数据框根据需要有3中转换方式 执行结果:    0 0  A 1  B 2  C 执行结果:            

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包