c# - dinamicas - ¿Cómo escribir este SQL de Linq como una consulta dinámica(usando cadenas)?
dynamic linq c# (2)
Pase a la "pregunta específica" según sea necesario. Algunos antecedentes:
El escenario: tengo un conjunto de productos con un filtro de "profundización" (Objeto de consulta) poblado con DDL. Cada selección progresiva de DDL limitará aún más la lista de productos, así como también las opciones que quedan para los DDL. Por ejemplo, seleccionar un martillo de herramientas limita los Tamaños de Producto para mostrar solo los tamaños de martillo.
Configuración actual: Creé un objeto de consulta, lo envié a un repositorio y alimenté cada opción a una "función de tabla valorada" donde los valores nulos representan "obtener todos los productos".
Considero que es un buen esfuerzo, pero está lejos de ser aceptable para DDD. Quiero evitar cualquier "programación" en SQL, con la esperanza de hacer todo con un repositorio. Los comentarios sobre este tema serán apreciados.
Pregunta específica
¿Cómo volvería a escribir esta consulta como una consulta dinámica ? Un enlace a algo así como 101 Ejemplos de Linq sería fantástico, pero con un alcance de Consulta dinámica. Realmente quiero pasarle a este método el campo entre comillas "" para el cual quiero una lista de opciones y cuántos productos tienen esa opción.
from p in db.Products
group p by p.ProductSize into g
select new Category {
PropertyType = g.Key,
Count = g.Count() }
Cada opción DDL tendrá "La selección (21)" donde el (21) es la cantidad de productos que tienen ese atributo. Al seleccionar una opción, todos los demás DDL restantes se actualizarán con las opciones y recuentos restantes.
Editar: notas adicionales:
.OrderBy("it.City") // "it" refers to the entire record
.GroupBy("City", "new(City)") // This produces a unique list of City
.Select("it.Count()") //This gives a list of counts... getting closer
.Select("key") // Selects a list of unique City
.Select("new (key, count() as string)") // +1 to me LOL. key is a row of group
.GroupBy("new (City, Manufacturer)", "City") // New = list of fields to group by
.GroupBy("City", "new (Manufacturer, Size)") // Second parameter is a projection
Product
.Where("ProductType == @0", "Maps")
.GroupBy("new(City)", "new ( null as string)")// Projection not available later?
.Select("new (key.City, it.count() as string)")// GroupBy new makes key an object
Product
.Where("ProductType == @0", "Maps")
.GroupBy("new(City)", "new ( null as string)")// Projection not available later?
.Select("new (key.City, it as object)")// the it object is the result of GroupBy
var a = Product
.Where("ProductType == @0", "Maps")
.GroupBy("@0", "it", "City") // This fails to group Product at all
.Select("new ( Key, it as Product )"); // "it" is property cast though
Lo que he aprendido hasta ahora es que LinqPad es fantástico, pero aún estoy buscando una respuesta. Eventualmente, una investigación completamente aleatoria como esta prevalecerá, supongo. LOL.
Editar:
Jon Skeet tuvo una idea fantástica: lanzar lo que necesito como IGrouping<string, Product>
. ¡Gracias a Jon Skeet! Una vez que lances el objeto, puedes enumerar los conjuntos y enviar los resultados a una lista separada.
No estoy seguro de cómo hacer esto usando la sintaxis de Query (como la anterior), pero usando la sintaxis del Método, podemos usar una expresión <Func <como se muestra a continuación. Este ejemplo funciona en contra de la base de datos de AdventureWorks SQL Server (tabla Productos) y le permite especificar qué columna agrupar utilizando una cadena (en esta muestra he elegido Tamaño)
using System;
using System.Linq;
using System.Linq.Expressions;
namespace LinqResearch
{
public class Program
{
[STAThread]
static void Main()
{
string columnToGroupBy = "Size";
// generate the dynamic Expression<Func<Product, string>>
ParameterExpression p = Expression.Parameter(typeof(Product), "p");
var selector = Expression.Lambda<Func<Product, string>>(
Expression.Property(p, columnToGroupBy),
p
);
using (LinqDataContext dataContext = new LinqDataContext())
{
/* using "selector" caluclated above which is automatically
compiled when the query runs */
var results = dataContext
.Products
.GroupBy(selector)
.Select((group) => new {
Key = group.Key,
Count = group.Count()
});
foreach(var result in results)
Console.WriteLine("{0}: {1}", result.Key, result.Count);
}
Console.ReadKey();
}
}
}
Si echa un vistazo a los bits C # , el autor explica cómo crear filtros en cascada utilizando datos dinámicos. No parece que uses datos dinámicos, pero tiene un buen generador de expresiones que puede ser útil para ti. Consulte BuildQueryBody y luego la siguiente sección de métodos de extensión en Iqueryable.
Como no está utilizando datos dinámicos, tendrá que ocuparse de no tener acceso a un objeto "MetaForeignKeyColumn", pero sospecho que su enfoque podría ayudarlo con su pregunta.
Espero que esto ayude.