如何在C#中将DataTable转换为泛型列表 [英] How to Convert DataTable to Generic List in C#

查看:82
本文介绍了如何在C#中将DataTable转换为泛型列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将C#DataTable转换为通用集合列表

I need to convert C# DataTable to Generic Collection List

DataTable Columns Respectively

 1. EmpId  (this is Int DataType)
 2. EmpName   (this is varchar DataType)
 3. EmpAddress  (this is varchar DataType)
 4. EmpPhone  (this is varchar DataType)
 5. Status   (this is Boolean DataType)
 6. EmpRelationKey (this is int DataType)

所以我的数据表包含上述字段的值.在这里,我需要将此值分配到我的列表中

so my DataTable Contains Values for above fields. here i need to assign this value into my list

分别为我的列表变量

class Employee
{
protected int EmpId  ;
protected string EmpName =String.Empty;
protected string EmpAddress  = String.Empty;
protected string EmpPhone  = String.Empty;
protected bool Status ;
protected int EmpRelationKey ;
}

Declaring List
List<Employee> Emp= new List<Employee>

所以现在我需要将DataTable值分配给此列表.该代码应该非常专业.

so now i need to assign DataTable values to this List. the code should be very professional.

我已经尝试过这种方法

List<Employee>employees = new List<Employee>();  

foreach (DataRow row in dt.Rows)  
{  
   employees.Add(new Employee  
   {  
   EmpId  = Convert.ToInt32(row["EmpId"]), 
   EmpName = row["EmpName"].ToString() ,
   EmpAddress =   row["EmpName"].ToString(),
   Emphone =   row["EmpPhone"].ToString(),
   Status = Convert.toBoolean(row["Status"])
   });  
}   

但是我不想提及列名,是否还有其他方法可以分配值而不提及DataTable中的每个列名

but i don't want to mention column names , is there any other ways to assign values without mentioning each and every column name from DataTable

推荐答案

using System.Reflection;

然后

public static List<T> BindList<T>(DataTable dt)
{
    // Example 1:
    // Get private fields + non properties
    //var fields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

    // Example 2: Your case
    // Get all public fields
    var fields = typeof(T).GetFields();

    List<T> lst = new List<T>();

    foreach (DataRow dr in dt.Rows)
    {
        // Create the object of T
        var ob = Activator.CreateInstance<T>();

        foreach (var fieldInfo in fields)
        {
            foreach (DataColumn dc in dt.Columns)
            {
                // Matching the columns with fields
                if (fieldInfo.Name == dc.ColumnName)
                {
                    // Get the value from the datatable cell
                    object value = dr[dc.ColumnName];

                    // Set the value into the object
                    fieldInfo.SetValue(ob, value);
                    break;
                }
            }
        }

        lst.Add(ob);
    }

    return lst;
}

用法示例:

DataTable dt1 = SqlHelper.GetTable("select * from employee;");
List<Employee> employees = BindList<Employee>(dt1);

DataTable dt2 = SqlHelper.GetTable("select * from membership;");
List<Membership> lstMembership = BindList<Membership>(dt2);

DataTable dt3 = SqlHelper.GetTable("select * from car order by name;");
List<Car> lstCar = BindList<Car>(dt3);

====================

=====================

上面的示例假定保存在DataTable中的数据与 Class对象的字段具有相同的数据类型.

Above example assume that the data holds inside the DataTable has the same data type as your Class object's fields.

如果数据与类对象的字段不同怎么办?

What if the data is not same as your class object's fields?

例如 null ?

因此,您可能需要扩展该方法,以防万一两种数据类型都不相同.

So, you might want to extend the method to take care just in case both data type are not the same.

public static List<T> BindList<T>(DataTable dt)
{
    // Example 1:
    // Get private fields + non properties
    //var fields = typeof(T).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

    // Example 2: Your case
    // Get all public fields
    var fields = typeof(T).GetFields();

    List<T> lst = new List<T>();

    foreach (DataRow dr in dt.Rows)
    {
        // Create the object of T
        var ob = Activator.CreateInstance<T>();

        foreach (var fieldInfo in fields)
        {
            foreach (DataColumn dc in dt.Columns)
            {
                // Matching the columns with fields
                if (fieldInfo.Name == dc.ColumnName)
                {
                    Type type = fieldInfo.FieldType;

                    // Get the value from the datatable cell
                    object value = GetValue(dr[dc.ColumnName], type);

                    // Set the value into the object
                    fieldInfo.SetValue(ob, value);
                    break;
                }
            }
        }

        lst.Add(ob);
    }

    return lst;
}

static object GetValue(object ob, Type targetType)
{
    if (targetType == null)
    {
        return null;
    }
    else if (targetType == typeof(String))
    {
        return ob + "";
    }
    else if (targetType == typeof(int))
    {
        int i = 0;
        int.TryParse(ob + "", out i);
        return i;
    }
    else if (targetType == typeof(short))
    {
        short i = 0;
        short.TryParse(ob + "", out i);
        return i;
    }
    else if (targetType == typeof(long))
    {
        long i = 0;
        long.TryParse(ob + "", out i);
        return i;
    }
    else if (targetType == typeof(ushort))
    {
        ushort i = 0;
        ushort.TryParse(ob + "", out i);
        return i;
    }
    else if (targetType == typeof(uint))
    {
        uint i = 0;
        uint.TryParse(ob + "", out i);
        return i;
    }
    else if (targetType == typeof(ulong))
    {
        ulong i = 0;
        ulong.TryParse(ob + "", out i);
        return i;
    }
    else if (targetType == typeof(double))
    {
        double i = 0;
        double.TryParse(ob + "", out i);
        return i;
    }
    else if (targetType == typeof(DateTime))
    {
        // do the parsing here...
    }
    else if (targetType == typeof(bool))
    {
        // do the parsing here...
    }
    else if (targetType == typeof(decimal))
    {
        // do the parsing here...
    }
    else if (targetType == typeof(float))
    {
        // do the parsing here...
    }
    else if (targetType == typeof(byte))
    {
        // do the parsing here...
    }
    else if (targetType == typeof(sbyte))
    {
        // do the parsing here...
    }
    else if........
    ..................

    return ob;
}

这篇关于如何在C#中将DataTable转换为泛型列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆