it-swarm.com.de

Wie konvertiert man DataTable in die Klasse Object?

Ich habe bereits eine Anwendung entwickelt, die DataTable überall zurückgibt.

Jetzt möchte mein Client konvertieren (verwenden Sie einen Teil mit Service-Stack), daher muss ich DTO (Objekte) in meiner Anwendung zurückgeben.

Ich möchte meine vorhandenen gespeicherten Prozeduren nicht ändern oder gar nicht so weit wie möglich LINQ verwenden (ich bin mir mit LINQ nicht allzu sehr bewusst).

Für kleine Funktionen kann Linq kein Problem verwenden.

Meine Frage ist: Wie kann ich meine DataTable in Objekte dieser Klasse umwandeln?

Der Beispielcode ist unten

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

Ich weiß, oben ist zeitaufwändig und deshalb versuche ich eine alternative Lösung zu finden.

Gibt es einen alternativen Weg (ich denke, LINQ zu DataTable), durch den die Zeilen der Tabellen direkt in List<Class1> konvertiert werden?

So kann ich Objekte in meinem Service-Stack zurückgeben und fortfahren.

25
amit patel

DataTable initialisieren:

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

Abfrage selbst:

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

Amit, ich habe einen Weg gebraucht, um dies mit weniger Kodierung und effizienterem Weg zu erreichen.

aber es verwendet Linq.

Ich habe es hier gepostet, weil vielleicht die Antwort anderen SO hilft.

Der folgende DAL-Code konvertiert ein datierbares Objekt in die Liste von YourViewModel und ist leicht verständlich.

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

Nun ist die Methode, die Methode zu übergeben und aufzurufen, unten.

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

Bis zum Datum fand ich für viele meiner Anwendungen die beste Struktur, um Daten zu erhalten .

6
Bharat

Vielleicht möchten Sie sich den Code hier anschauen. Obwohl Ihre Frage nicht direkt beantwortet wird, können Sie die generischen Klassentypen anpassen, die zur Zuordnung zwischen Datenklassen und Geschäftsobjekten verwendet werden.

Auch mit generic führen Sie den Konvertierungsprozess so schnell wie möglich aus.

0
ChrisBD