.net - example - dynamic object c#
Vinculando un objeto GridView a un objeto Dynamic o ExpandoObject (6)
Estoy usando el ORM masivo de Rob Conery, y no he podido vincular el ExpandoObject
resultante a un GridView
.
Encontré otra pregunta de Stackoverflow que sugiere usar un marco llamado impromptu, pero no estoy seguro de si eso funcionaría para esto. Si sabe que sí, proporcione un ejemplo de código para convertir realmente un ExpandoObject
en algo a lo que se pueda enlazar el control GridView
.
En el peor de los casos, ¿alguien ha implementado un método adicional (que se pueda compartir) para que Massive convierta el ExpandoObject
resultante en un POCO?
Cualquier ayuda es muy apreciada. Gracias.
Adapté la respuesta aceptada de Brian para ser un poco más concisa y LINQ-y:
public static DataTable ToDataTable(this IEnumerable<dynamic> items)
{
var list = items.Cast<IDictionary<string, object>>().ToList();
if(!list.Any()) return null;
var table = new DataTable();
list.First().Keys.Each(x => table.Columns.Add(x));
list.Each(x => x.Values.Each(y => table.Rows.Add(y)));
return table;
}
(Esto supone que ha definido una extensión IEnumerable.Each, que ha tenido cada base de código en la que he trabajado).
Como no puede enlazar con un ExpandoObject, puede convertir los datos en una tabla de datos. Este método de extensión lo hará por ti. Podría enviar esto para su inclusión a Massive.
/// <summary>
/// Extension method to convert dynamic data to a DataTable. Useful for databinding.
/// </summary>
/// <param name="items"></param>
/// <returns>A DataTable with the copied dynamic data.</returns>
public static DataTable ToDataTable(this IEnumerable<dynamic> items) {
var data = items.ToArray();
if (data.Count() == 0) return null;
var dt = new DataTable();
foreach(var key in ((IDictionary<string, object>)data[0]).Keys) {
dt.Columns.Add(key);
}
foreach (var d in data) {
dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
}
return dt;
}
Llegué a este hilo después de investigar sobre el mismo tema, no encontré ninguna solución, pero construí la mía porque necesitaba desesperadamente esta. Así que aquí está mi solución sin ir a POCO que realmente funciona.
// Fill "list" with your dynamic objects.
// cast a dynamic object to dictionary so we get the properties from it.
var props = list[0] as IDictionary<string, object>;
// create a datatable
var table = new System.Data.DataTable();
foreach (var c in props.Keys)
table.Columns.Add(new DataColumn(c));
foreach (var o in list)
{
var row = table.NewRow();
var op = o as IDictionary<string, object>;
foreach (var p in op.Keys)
{
row[p] = op[p];
}
table.Rows.Add(row);
}
¡Y simplemente une esta tabla a tu cuadrícula!
Lo probé y funcionó para mí.
Ok, aparentemente a partir de ahora, simplemente no puede enlazar un control GridView a una instancia de ExpandoObject. Tuve que usar la reflexión para convertir ExpandoObject a una clase POCO.
Si estamos hablando de GridView (es decir, no de WPF), Impromptu puede representar un expando a un poco dada una interfaz. Digamos que tenemos una lista de expando que puedes convertirlos a poco:
IEnumerable<IMyInterface> listOfPocos
= Impropmtu.AllActLike<IMyInterface>(listOfExpandos, typeof(INotifyPropertyChanged));
adaptándose de la respuesta de Ben
public static DataTable ToDataTable(this IEnumerable<dynamic> items)
{
if (!items.Any()) return null;
var table = new DataTable();
bool isFirst = true;
items.Cast<IDictionary<string, object>>().ToList().ForEach(x =>
{
if (isFirst)
{
x.Keys.Select(y => table.Columns.Add(y)).ToList();
isFirst = false;
}
table.Rows.Add(x.Values.ToArray());
});
return table;
}