J'ai déjà développé une application qui renvoie DataTable partout.
Maintenant, mon client veut convertir (utiliser une partie de la pile de services), je dois donc renvoyer des objets DTO dans mon application.
Je ne veux pas changer mes procédures stockées existantes ou même ne pas vouloir utiliser LINQ autant que possible (je ne suis pas trop au courant avec LINQ).
Pour les petites fonctionnalités, je ne peux utiliser aucun problème avec Linq.
Ma question est la suivante: comment puis-je changer ma DataTable
en objets de cette classe?
L'exemple de code est ci-dessous
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());
Je sais, ce qui précède prend beaucoup de temps et j'essaie donc de trouver une solution alternative.
Existe-t-il un moyen alternatif (j'imagine, LINQ to DataTable) de convertir directement les lignes de tables en List<Class1>
?
Je peux donc retourner des objets dans ma pile de services et continuer.
Initialiser 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 });
}
Requête elle-même:
IList<Class1> items = dt.AsEnumerable().Select(row =>
new Class1
{
id = row.Field<string>("id"),
name = row.Field<string>("name")
}).ToList();
Amit, j'ai utilisé un moyen pour y parvenir avec moins de codage et de manière plus efficace.
mais il utilise Linq.
Je l'ai posté ici parce que peut-être la réponse aide-t-elle les autres.
Le code DAL ci-dessous convertit un objet datatable en une liste de YourViewModel facile à comprendre.
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;
}
}
Maintenant, le moyen de passer et d'appeler la méthode est ci-dessous.
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]);
}
Jusqu'à la date limite, pour beaucoup de mes applications, j’ai trouvé cela comme la meilleure structure pour obtenir des données .
Vous voudrez peut-être jeter un coup d'œil au code ici . Bien que cela ne réponde pas directement à votre question, vous pouvez adapter les types de classe génériques utilisés pour mapper des classes de données et des objets métier.
De plus, en utilisant générique, vous exécutez le processus de conversion aussi rapidement que possible.