programing

DataTable을 클래스 Object로 변환하는 방법은 무엇입니까?

linuxpc 2023. 8. 24. 21:50
반응형

DataTable을 클래스 Object로 변환하는 방법은 무엇입니까?

나는 이미 반환되는 애플리케이션을 개발했습니다.DataTable온통.

이제 클라이언트가 변환(서비스 스택을 사용하여 일부 부분 사용)을 원하므로 반환해야 합니다.DTO (objects)내 신청으로

기존 저장 프로시저를 변경하거나 LINQ를 최대한 사용하고 싶지 않습니다(LINQ에 대해 잘 알지 못합니다).

작은 기능을 위해, 저는 문제없이 Linkq를 사용할 수 있습니다.

제 질문은 다음과 같습니다. 어떻게 변경할 수 있습니까?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>?

서비스 스택의 개체를 반환하고 계속 진행할 수 있습니다.

데이터 테이블 초기화:

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();

Amit, 저는 이것을 더 적은 코딩과 더 효율적인 방법으로 달성하기 위해 한 가지 방법을 사용했습니다.

하지만 그것은 Linq를 사용합니다.

아마 다른 SO들에게 도움이 될 수도 있기 때문에 여기에 올렸습니다.

아래의 DAL 코드는 데이터 테이블 객체를 당신의 뷰 모델 목록으로 변환하며 이해하기 쉽습니다.

public static class DAL
{
        public static string connectionString = ConfigurationManager.ConnectionStrings["YourWebConfigConnection"].ConnectionString;

        // function that creates a list of an object from the given data table
        public static List<T> CreateListFromTable<T>(DataTable tbl) where T : new()
        {
            // define return list
            List<T> lst = new List<T>();

            // go through each row
            foreach (DataRow r in tbl.Rows)
            {
                // add to the list
                lst.Add(CreateItemFromRow<T>(r));
            }

            // return the list
            return lst;
        }

        // function that creates an object from the given data row
        public static T CreateItemFromRow<T>(DataRow row) where T : new()
        {
            // create a new object
            T item = new T();

            // set the item
            SetItemFromRow(item, row);

            // return 
            return item;
        }

        public static void SetItemFromRow<T>(T item, DataRow row) where T : new()
        {
            // go through each column
            foreach (DataColumn c in row.Table.Columns)
            {
                // find the property for the column
                PropertyInfo p = item.GetType().GetProperty(c.ColumnName);

                // if exists, set the value
                if (p != null && row[c] != DBNull.Value)
                {
                    p.SetValue(item, row[c], null);
                }
            }
        }

        //call stored procedure to get data.
        public static DataSet GetRecordWithExtendedTimeOut(string SPName, params SqlParameter[] SqlPrms)
        {
            DataSet ds = new DataSet();
            SqlCommand cmd = new SqlCommand();
            SqlDataAdapter da = new SqlDataAdapter();
            SqlConnection con = new SqlConnection(connectionString);

            try
            {
                cmd = new SqlCommand(SPName, con);
                cmd.Parameters.AddRange(SqlPrms);
                cmd.CommandTimeout = 240;
                cmd.CommandType = CommandType.StoredProcedure;
                da.SelectCommand = cmd;
                da.Fill(ds);
            }
            catch (Exception ex)
            {
               return ex;
            }

            return ds;
        }
}

자, 통과 방법과 통화 방법은 아래와 같습니다.

    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]);                
    }      

지금까지 많은 애플리케이션에서 데이터를 얻기 위한 최상의 구조라고 생각했습니다.

이것을 보고 깨달았죠. 이것은 한 종류의 물체에서 다른 종류의 물체로 옮겨가는 것입니다. 기본적으로 우리는 적절한 반사를 하려고 노력하고 있습니다.

다른 분야 간의 관계를 구성하는 적절한 방법이 있지만 클래스 정의를 제공하면 뉴턴소프트에서 쉽게 수행할 수 있습니다.

프로세스:DataSet/DataTable(Serialize) ==> Json(Deserialize) ==> Target Object List 이 예에서는 OP로서 다음을 수행합니다.

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

이제 데이터 테이블이 일반 문자열로 직렬화됩니다.다음을 수행합니다.

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

이제 모든 DataTable 행이 포함된 List를 개별 객체로 만들어야 합니다.

2023년 기준으로 훨씬 단순하고 버전이 낮은 코드

public class ClassName
{
   public int Id { get; set; }
   public String FirstName { get; set; }
   public String LastName { get; set; }
}

클래스 객체 목록의 경우

DataTable dt = new DataTable();

var _objectList = JArray.FromObject(dt).ToObject<List<Venues>>();

클래스 개체의 경우

DataTable dt = new DataTable();

var _object = JArray.FromObject(dt)[].ToObject<Venues>();

Vb입니다.넷 버전:

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

json convert로 하면 비용이 많이 드나요?하지만 적어도 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

언급URL : https://stackoverflow.com/questions/8008389/how-to-convert-datatable-to-class-object

반응형