Si solo vas a usarlo una vez, probablemente sea correcto, pero si lo haces mucho deberías tratar de hacer algunas cosas más genéricas. Escribí una publicación de blog sobre cómo escribir un método de extensión para DataTable
que crea una lista de objetos. Funciona mediante la convención de que las propiedades del objeto deben tener el mismo nombre que las columnas en el procedimiento almacenado (me gustaría cambiar el nombre en el procedimiento almacenado si pudiera):
public static class DataTableExtensions
{
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
{
var item = CreateItemFromRow<T>((DataRow)row, properties);
result.Add(item);
}
return result;
}
public static IList<T> ToList<T>(this DataTable table, Dictionary<string, string> mappings) where T : new()
{
IList<PropertyInfo> properties = typeof(T).GetProperties().ToList();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
{
var item = CreateItemFromRow<T>((DataRow)row, properties, mappings);
result.Add(item);
}
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
property.SetValue(item, row[property.Name], null);
}
return item;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties, Dictionary<string, string> mappings) where T : new()
{
T item = new T();
foreach (var property in properties)
{
if(mappings.ContainsKey(property.Name))
property.SetValue(item, row[mappings[property.Name]], null);
}
return item;
}
}
Ahora puede simplemente llamar
var items = dt.ToList<Item>();
o
var mappings = new Dictionary<string,string>();
mappings.Add("ItemId", "item_id");
mappings.Add("ItemName ", "item_name");
mappings.Add("Price ", "price);
var items = dt.ToList<Item>(mappings);
La entrada del blog está aquí: http://blog.tomasjansson.com/2010/11/convert-datatable-to-generic-list-extension
Hay muchas formas en que puede ampliar esto, puede incluir algún tipo de diccionario de mapeo que indique a la extensión cómo mapear las columnas, de esa forma no es necesario que los nombres coincidan. O puede agregar una lista de nombres de propiedad que le gustaría excluir en la asignación.
Actualización: Su objeto (Item
) que está creando debe tener un constructor predeterminado, de lo contrario, el método privado no podrá crearlo. Dado que la forma en que funciona la solución es primero crear el objeto que usar las propiedades que se obtienen de la reflexión para establecer los valores del objeto.
Actualización 2: He añadido la parte con el diccionario de asignaciones, pero no lo he probado, por lo que podría no compilarse. Sin embargo, el concepto está ahí y creo que funciona.
Por qué el load() 'clase de artículos en el interior? –
Porque no tiene sentido clasificarlo en una clase diferente. Tengo muchos casos como este y no puedo tener cientos de clases que solo devuelven el resultado de la consulta. – Naor
@Nor lo hacen estático al menos .. – nawfal