[转]DataTable转换为List<Model>的通用类_se7en3_新浪博客

本文介绍了一种将DataTable转换为任意模型类型的通用方法,通过反射和泛型实现,适用于多种模型,提高了开发效率。

在开发中,把查询结果以DataTable返回很方便,但是在检索数据时又很麻烦,没有模型类型检索方便。

所以很多人都是按照以下方式做的:

// 获得查询结果
DataTable dt = DbHelper.ExecuteDataTable(...);
// 把DataTable转换为IList<UserInfo>
IList<UserInfo> users = ConvertToUserInfo(dt);

 

问题:如果此系统有几十上百个模型,那不是每个模型中都要写个把DataTable转换为此模型的方法吗?
解决:能不能写个通用类,可以把DataTable转换为任何模型,呵呵,这就需要利用反射和泛型

 

不多说,核心代码如下,经过测试,性能不错,大家可以根据实际情况改善

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Data;
using  System.Reflection;

namespace  NCL.Data
{
    
///   <summary>
    
///  实体转换辅助类
    
///   </summary>
     public   class  ModelConvertHelper < T >   where   T :  new ()
    {
        
public   static  IList < T >  ConvertToModel(DataTable dt)
        {
            
//  定义集合
            IList < T >  ts  =   new  List < T > ();

            
//  获得此模型的类型
            Type type  =   typeof (T);

            
string  tempName  =   "" ;

            
foreach  (DataRow dr  in  dt.Rows)
            {
                T t 
=   new  T();

                
//  获得此模型的公共属性
                PropertyInfo[] propertys  =  t.GetType().GetProperties();

                
foreach  (PropertyInfo pi  in  propertys)
                {
                    tempName 
=  pi.Name;

                    
//  检查DataTable是否包含此列
                     if  (dt.Columns.Contains(tempName))
                    {
                        
//  判断此属性是否有Setter
                         if  ( ! pi.CanWrite)  continue ;

                        
object  value  =  dr[tempName];
                        
if  (value  !=  DBNull.Value)
                            pi.SetValue(t, value, 
null );
                    }
                }

                ts.Add(t);
            }

            
return  ts;

        }
    }
}

 

使用方式:

// 获得查询结果
DataTable dt = DbHelper.ExecuteDataTable(...);
// 把DataTable转换为IList<UserInfo>
IList<UserInfo> users = ModelConvertHelper<UserInfo>.ConvertToModel(dt);

 

 

<think>好的,我现在需要解决用户的问题:如何将C#中的DataTable某一列数据转换为List<string>。首先,我应该回忆一下用户提供的引用内容,看看有没有相关的例子或者方法。 用户提供的引用中有几个方法涉及到DataTableList<T>,比如引用1中的ConvertTo方法,引用3中的ToDataList扩展方法,还有引用4中的ToList扩展方法。这些方法主要是将整个DataTable转换为实体的列表,但用户现在只需要某一列的数据为字符串列表,所以需要调整这些方法。 首先,用户的问题更具体,只需要某一列,而不是整个行转换为对象。因此,可能需要遍历DataTable的每一行,提取指定列的值,然后添加到List<string>中。这应该是一个直接的方法,不需要使用反射或者泛型实体转换。 引用中的例子大多使用循环遍历DataRow,比如引用1中的foreach循环处理每一行。所以,我可以参考这个思路,遍历DataTable的Rows集合,取每个行的指定列的值,转换为字符串,然后加入列表。 需要注意的是,列名是否正确,以及是否有空值的情况。例如,如果某一行的该列为DBNull.Value,直接转换可能会出错,可能需要处理为null或者空字符串。用户可能希望保持原样,或者进行一些处理,但问题中没有提到,所以暂时假设列存在且值都可转换为字符串。 另外,用户可能想要最简洁的代码,比如使用LINQ来简化循环。例如,使用Cast<DataRow>()和Select()方法,将每行的字段值提取出来。这样可以一行代码完成转换,代码更简洁。 例如,使用这样的代码: List<string> list = dataTable.AsEnumerable() .Select(row => row["ColumnName"].ToString()) .ToList(); 这里需要注意AsEnumerable()是System.Data.DataSetExtensions中的方法,需要引用对应的命名空间。如果用户的项目中没有引用,可能需要添加。 另外,如果列中存在null值,ToString()可能会抛出异常,但根据DataTable的结构,通常字段为字符串型的话,可能存储的是空字符串而不是null。不过,为了安全起见,可以改为使用Convert.ToString(row["ColumnName"]),这样即使字段是DBNull或其他型,也能正确转换为字符串。 总结步骤: 1. 确保列名正确存在。 2. 遍历DataTable的每一行。 3. 提取指定列的值,转换为字符串。 4. 收集到List<string>中。 可能的异常处理包括列不存在,或者值为DBNull,需要根据具体情况处理。例如,使用Field<T>扩展方法,可能更安全,但需要处理转换。 比如: List<string> list = dataTable.AsEnumerable() .Select(row => row.Field<string>("ColumnName")) .ToList(); 但这样如果列的型不是string,可能会有问题。或者,可以统一用ToString(),或者Convert.ToString()。 另外,用户可能需要处理不同的数据型,例如将整数列转换为字符串列表,这时候ToString()是可行的。 因此,给出两种方法:一种是直接遍历循环添加,另一种是使用LINQ更简洁的方式。同时提醒注意事项,如列名正确性和空值处理。 检查用户提供的引用,引用4中提到使用扩展方法,可能用户希望一个现成的扩展方法,但问题中只需要一次性的转换,所以直接代码即可。 最后,生成示例代码,并说明注意事项,确保用户能够顺利实现。</think>要将C#中的DataTable某一列数据转换为$List<string>$,可通过以下步骤实现: ### 方法实现 1. **遍历DataTable行集合**,提取指定列的值 2. **型安全处理**:使用`Field<T>`扩展方法或`Convert.ToString`避免空值异常 3. **LINQ简化代码**:通过`AsEnumerable()`和`Select()`快速转换 ```csharp // 使用LINQ转换(需引用System.Data.DataSetExtensions和System.Linq) List<string> columnData = dataTable.AsEnumerable() .Select(row => row.Field<string>("ColumnName")) // 或 row["ColumnName"].ToString() .ToList(); // 传统循环方式(无需LINQ) List<string> list = new List<string>(); foreach (DataRow row in dataTable.Rows) { list.Add(Convert.ToString(row["ColumnName"])); // 安全处理DBNull和转换 } ``` ### 关键注意事项 1. **列名验证**:确保列存在,否则会抛出`ArgumentException` ```csharp if (!dataTable.Columns.Contains("ColumnName")) throw new ArgumentException("列不存在"); ``` 2. **空值处理**:若列可能包含`DBNull.Value`,优先使用`Field<string>`配合`Convert.ToString`[^4] 3. **性能优化**:大数据量时,传统循环效率高于LINQ[^2] ### 扩展应用 若需将**整列转换为其他数据型**(如数值),可调整型参数: ```csharp List<int> numbers = dataTable.AsEnumerable() .Select(row => row.Field<int>("NumericColumn")) .ToList(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值