如何将DataTable转换为类Object

时间:2011-11-04 11:13:46

标签: c# asp.net .net linq datatable

我已经开发了一个可以在任何地方返回DataTable的应用程序。

现在我的客户端想要转换(使用服务堆栈使用某些部分),所以我需要在我的应用程序中返回DTO(对象)。

我不想更改现有的存储过程,甚至不想尽可能多地使用LINQ(我对LINQ并不太了解)。

对于小功能,我可以使用Linq没问题。

我的问题是:如何将DataTable更改为该类的对象?

示例代码位于

之下
string s = DateTime.Now.ToString();
DataTable dt = new DataTable();

dt.Columns.Add("id");
dt.Columns.Add("name");

for (int i = 0; i < 5000000; i++)
{
    DataRow dr = dt.NewRow();
    dr["id"] = i.ToString();
    dr["name"] = "name" + i.ToString();
    dt.Rows.Add(dr);

    dt.AcceptChanges();
}

List<Class1> clslist = new List<Class1>();

for (int i = 0; i < dt.Rows.Count; i++)
{
    Class1 cls = new Class1();
    cls.id = dt.Rows[i]["id"].ToString();
    cls.name = dt.Rows[i]["name"].ToString();
    clslist.Add(cls);
}

Response.Write(s);
Response.Write("<br>");
Response.Write(DateTime.Now.ToString());

我知道,上面是耗时的,所以我想找到一个替代解决方案。

有没有其他方法(我猜,LINQ to DataTable)可以通过它直接将表行转换为List<Class1>

所以我可以在服务堆栈中返回对象并继续。

6 个答案:

答案 0 :(得分:66)

初始化DataTable:

DataTable dt = new DataTable(); 
dt.Columns.Add("id", typeof(String)); 
dt.Columns.Add("name", typeof(String)); 
for (int i = 0; i < 5; i++)
{
    string index = i.ToString();
    dt.Rows.Add(new object[] { index, "name" + index });
}

查询自己:

IList<Class1> items = dt.AsEnumerable().Select(row => 
    new Class1
        {
            id = row.Field<string>("id"),
            name = row.Field<string>("name")
        }).ToList();

答案 1 :(得分:8)

阿米特,我用一种方法用更少的编码和更有效的方式实现这一目标。

但它使用Linq。

我在这里发布了,因为答案可能有助于其他SO。

  

DAL代码下方将数据表对象转换为YourViewModel列表,并且易于理解。

    DataSet ds = DAL.GetRecordWithExtendedTimeOut("ProcedureName");

    List<YourViewModel> model = new List<YourViewModel>();

    if (ds != null)
    {
        //Pass datatable from dataset to our DAL Method.
        model = DAL.CreateListFromTable<YourViewModel>(ds.Tables[0]);                
    }      
  

现在,传递和调用方法的方法如下。

 <a href="~/Home/Download_Excel_File" />
  

直到日期,对于我的许多应用程序,我发现这是获取数据的最佳结构

答案 2 :(得分:1)

这是Vb.Net版本:

Public Class Test
Public Property id As Integer
Public Property name As String
Public Property address As String
Public Property createdDate As Date

结束班级

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim x As Date = Now

    Debug.WriteLine("Begin: " & DateDiff(DateInterval.Second, x, Now) & "-" & Now)

    Dim dt As New DataTable
    dt.Columns.Add("id")
    dt.Columns.Add("name")
    dt.Columns.Add("address")
    dt.Columns.Add("createdDate")

    For i As Integer = 0 To 100000
        dt.Rows.Add(i, "name - " & i, "address - " & i, DateAdd(DateInterval.Second, i, Now))
    Next

    Debug.WriteLine("Datatable created: " & DateDiff(DateInterval.Second, x, Now) & "-" & Now)


    Dim items As IList(Of Test) = dt.AsEnumerable().[Select](Function(row) New _
            Test With {
                        .id = row.Field(Of String)("id"),
                        .name = row.Field(Of String)("name"),
                        .address = row.Field(Of String)("address"),
                        .createdDate = row.Field(Of String)("createdDate")
                       }).ToList()

    Debug.WriteLine("List created: " & DateDiff(DateInterval.Second, x, Now) & "-" & Now)

    Debug.WriteLine("Complated")

End Sub

答案 3 :(得分:1)

看着这个并意识到:它是从一种类型的对象到另一种类型的;基本上,我们正在努力进行适当的反思。

不同字段之间的关系有适当的构造方法,但是类定义已经完成,Newtonsoft.Json可以轻松完成

流程:DataSet/DataTable(序列化)==> Json(反序列化)==> 目标对象列表 在本例中作为 OP,只需执行以下操作:

string serializeddt = JsonConvert.SerializeObject(dt, Formatting.Indented);

现在数据表被序列化为一个普通字符串。 然后这样做:

List<Class1> clslist = JsonConvert.DeserializeObject<List<Class1>>(serialized, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

现在您应该拥有包含所有 DataTable 行作为单独对象的 List。

答案 4 :(得分:0)

哟可能想查看代码here。虽然它不直接回答您的问题,但您可以调整用于在数据类和业务对象之间进行映射的泛型类类型。

此外,通过使用通用,您可以尽快运行转换过程。

答案 5 :(得分:0)

通过json转换执行此操作是否非常昂贵?但是至少您有2行解决方案及其通用。不管您的数据表中包含的字段多于或少于对象类,这都没有关系:

Dim sSql = $"SELECT '{jobID}' AS ConfigNo, 'MainSettings' AS ParamName, VarNm AS ParamFieldName, 1 AS ParamSetId, Val1 AS ParamValue FROM StrSVar WHERE NmSp = '{sAppName} Params {jobID}'"
            Dim dtParameters As DataTable = DBLib.GetDatabaseData(sSql)

            Dim paramListObject As New List(Of ParameterListModel)()

            If (Not dtParameters Is Nothing And dtParameters.Rows.Count > 0) Then
                Dim json = Newtonsoft.Json.JsonConvert.SerializeObject(dtParameters).ToString()

                paramListObject = Newtonsoft.Json.JsonConvert.DeserializeObject(Of List(Of ParameterListModel))(json)
            End If
相关问题