Linq dinámico: creación de un método de extensión que produce un resultado JSON
Pregunta
Estoy atascado al intentar crear un método de extensión dinámico de LINQ que devuelva una cadena en formato JSON. Estoy usando System.Linq.Dynamic y Newtonsoft.Json y no puedo hacer que Linq.Dynamic analice "cell=new". objeto[]" parte.¿Quizás demasiado complejo?¿Algunas ideas?:
Mi método principal:
static void Main(string[] args)
{
NorthwindDataContext db = new NorthwindDataContext();
var query = db.Customers;
string json = JSonify<Customer>
.GetJsonTable(
query,
2,
10,
"CustomerID"
,
new string[]
{
"CustomerID",
"CompanyName",
"City",
"Country",
"Orders.Count"
});
Console.WriteLine(json);
}
Clase JSonify
public static class JSonify<T>
{
public static string GetJsonTable(
this IQueryable<T> query,
int pageNumber,
int pageSize,
string IDColumnName,
string[] columnNames)
{
string selectItems =
String.Format(@"
new
{
{{0}} as ID,
cell = new object[]{{{1}}}
}",
IDColumnName,
String.Join(",", columnNames));
var items = new
{
page = pageNumber,
total = query.Count(),
rows =
query
.Select(selectItems)
.Skip(pageNumber * pageSize)
.Take(pageSize)
};
return JavaScriptConvert.SerializeObject(items);
// Should produce this result:
// {
// "page":2,
// "total":91,
// "rows":
// [
// {"ID":"FAMIA","cell":["FAMIA","Familia Arquibaldo","Sao Paulo","Brazil",7]},
// {"ID":"FISSA","cell":["FISSA","FISSA Fabrica Inter. Salchichas S.A.","Madrid","Spain",0]},
// {"ID":"FOLIG","cell":["FOLIG","Folies gourmandes","Lille","France",5]},
// {"ID":"FOLKO","cell":["FOLKO","Folk och fä HB","Bräcke","Sweden",19]},
// {"ID":"FRANK","cell":["FRANK","Frankenversand","München","Germany",15]},
// {"ID":"FRANR","cell":["FRANR","France restauration","Nantes","France",3]},
// {"ID":"FRANS","cell":["FRANS","Franchi S.p.A.","Torino","Italy",6]},
// {"ID":"FURIB","cell":["FURIB","Furia Bacalhau e Frutos do Mar","Lisboa","Portugal",8]},
// {"ID":"GALED","cell":["GALED","Galería del gastrónomo","Barcelona","Spain",5]},
// {"ID":"GODOS","cell":["GODOS","Godos Cocina Típica","Sevilla","Spain",10]}
// ]
// }
}
}
Solución
Esto es realmente feo y puede haber algunos problemas con el reemplazo de la cadena, pero produce los resultados esperados:
public static class JSonify
{
public static string GetJsonTable<T>(
this IQueryable<T> query, int pageNumber, int pageSize, string IDColumnName, string[] columnNames)
{
string select = string.Format("new ({0} as ID, \"CELLSTART\" as CELLSTART, {1}, \"CELLEND\" as CELLEND)", IDColumnName, string.Join(",", columnNames));
var items = new
{
page = pageNumber,
total = query.Count(),
rows = query.Select(select).Skip((pageNumber - 1) * pageSize).Take(pageSize)
};
string json = JavaScriptConvert.SerializeObject(items);
json = json.Replace("\"CELLSTART\":\"CELLSTART\",", "\"cell\":[");
json = json.Replace(",\"CELLEND\":\"CELLEND\"", "]");
foreach (string column in columnNames)
{
json = json.Replace("\"" + column + "\":", "");
}
return json;
}
}
Otros consejos
static void Main(string[] args)
{
NorthwindDataContext db = new NorthwindDataContext();
var query = db.Customers;
string json = query.GetJsonTable<Customer>(2, 10, "CustomerID", new string[] {"CustomerID", "CompanyName", "City", "Country", "Orders.Count" });
}
public static class JSonify
{
public static string GetJsonTable<T>(
this IQueryable<T> query, int pageNumber, int pageSize, string IDColumnName, string[] columnNames)
{
string select = string.Format("new ({0} as ID, new ({1}) as cell)", IDColumnName, string.Join(",", columnNames));
var items = new
{
page = pageNumber,
total = query.Count(),
rows = query.Select(select).Skip((pageNumber - 1) * pageSize).Take(pageSize)
};
return JavaScriptConvert.SerializeObject(items);
}
}
Gracias por la rápida respuesta.Sin embargo, tenga en cuenta que la salida requerida no tiene nombres de propiedades en la matriz de "celdas" (es por eso que estaba usando objeto []):
"celda":["FAMIA","Familia Arquibaldo",...vs."cell":{"IDCliente":"FAMIA","NombreEmpresa","Familia Arquibaldo",...
El resultado está pensado para usarse con una grilla JQuery llamada "flexify" que requiere la salida en este formato.