una - procesando dinámicamente fórmulas creadas por el usuario c#
Crear consultas dinámicas con el marco de entidad (4)
He creado un repositorio genérico que debería ayudarte. Admite API uniformes para consultar y ordenar campos tanto conocidos como dinámicos:
//Filter on known fields
var keyboard = Query<Product>.Create(p=>p.Category=="Keyboard");
var keyboards = repository.Get(keyboard);
//Or filter on dynamic fields
var filter = Query<Product>.Create("Rating", OperationType.GreaterThan, 4)
var filteredKeyboards = repository.Get(filter);
//You can also combine two queries togather
var filterdKeyboards2 = repository.Get(keyboard.And(filter))
//Order it on known fields
var orderedKeyboard = keyboard.OrderBy(o=>o.Asc(p=>p.Name));
var orderedKeyboards = repository.Get(orderedKeyboard);
//Or order by on dynamic fields
var userOrdering = keyboard.OrderBy(o=>o.Asc("Name"));
var orderedKeyboards2 = repository.Get(userOrdering);
No sé sobre el objeto de búsqueda / DTO que está recibiendo, pero puede crear fácilmente un objeto de búsqueda genérico / DTO y puede asignarlo a un objeto Query en pocas líneas de código. Lo he usado en el pasado en torno a un servicio de WCF y me ha funcionado muy bien.
Me gustaría saber cuál es la mejor forma de crear consultas dinámicas con entity framework y linq.
Quiero crear un servicio que tenga muchos parámetros para ordenar y filtrar (más de 50). Obtendré el objeto de la interfaz gráfica de usuario, donde se rellenarán ... y la consulta se ejecutará desde un solo método de servicio.
Miré alrededor y vi que podía crear dinámicamente una cadena que se puede ejecutar al final de mi método. No me gusta mucho de esta manera. ¿Hay una mejor manera de hacer esto? Preferiblemente, escriba safe con cheque de compilación?
La única otra forma que conozco sería construir un IQueryable en función de los valores del filtro.
public List<Contact> Get(FilterValues filter)
{
using (var context = new AdventureWorksEntities())
{
IQueryable<Contact> query = context.Contacts.Where(c => c.ModifiedDate > DateTime.Now);
if (!string.IsNullOrEmpty(filter.FirstName))
{
query = query.Where(c => c.FirstName == filter.FirstName);
}
if (!string.IsNullOrEmpty(filter.LastName))
{
query = query.Where(c => c.LastName == filter.LastName);
}
return query.ToList();
}
}
Podría considerar crear el servicio utilizando los servicios de datos WCF y crear dinámicamente el URI para consultar su modelo de entidad.
Puede componer un IQueryable<T>
paso a paso. Suponiendo que tiene una clase FilterDefinition
que describe cómo el usuario quiere filtrar ...
public class FilterDefinition
{
public bool FilterByName { get; set; }
public string NameFrom { get; set; }
public string NameTo { get; set; }
public bool FilterByQuantity { get; set; }
public double QuantityFrom { get; set; }
public double QuantityTo { get; set; }
}
... entonces podrías construir una consulta como esta:
public IQueryable<SomeEntity> GetQuery(FilterDefinition filter)
{
IQueryable<SomeEntity> query = context.Set<SomeEntity>();
// assuming that you return all records when nothing is specified in the filter
if (filter.FilterByName)
query = query.Where(t =>
t.Name >= filter.NameFrom && t.Name <= filter.NameTo);
if (filter.FilterByQuantity)
query = query.Where(t =>
t.Quantity >= filter.QuantityFrom && t.Quantity <= filter.QuantityTo);
return query;
}