Me gustaría saber cuál es la mejor manera de crear consultas dinámicas con entity framework y linq.

Quiero crear un servicio que tiene muchos parámetros para ordenar y filtrar (más de 50). Voy a estar recibiendo objeto de gui donde estos serán llenados… y consulta va a ser ejecutado a partir de un único método de servicio.

Miré a mi alrededor Y vi que podía crear dinámicamente una cadena que puede ser ejecutada en el final de mi método. No me gusta mucho. Hay una manera mejor de hacer esto? Preferiblemente tipo de seguro con compilar el cheque?

InformationsquelleAutor Eduard | 2011-04-04

4 Comentarios

  1. 54

    Podría componer un IQueryable<T> paso por paso. Suponiendo que se tiene una FilterDefinition de la clase que describe cómo el usuario desea 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 se podría construir una consulta así:

    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;
    }
    • Gracias, pero, ¿cómo dows este trabajo? No esta tirar todos los datos de la base de datos y, a continuación, paso por paso limitar a la deseada conjunto de datos??
    • No, aprovecha deferred execution (blogs.msdn.com/b/charlie/archive/2007/12/09/…). Eso significa que IQueryable<T> que se compone en el ejemplo anterior es sólo una expresión de consulta que describe cómo los datos son filtrados. El real de ejecución de la consulta no está en el ejemplo en todo. Ejecutar la consulta, a continuación, mediante la aplicación de un «codiciosos» operador IQueryable<T>, por ejemplo query.ToList(). En este punto – y no antes – la expresión de la consulta se traduce en SQL y se envía al servidor.
    • No es tan bueno porque se supone que SomeEntity tiene Nombre y la Cantidad de campos, así que esto es sólo la mitad de dinámica.
    • Es allí cualquier manera de definir and o or dinámicamente?
    • también no permitir la dinámica de operadores condicionales, por ejemplo, si quería, de forma dinámica, permiten a los usuarios filtrar por «costo > 10» o «cost < 10»
    • Esto es exactamente lo que estoy buscando.

  2. 33

    La única otra manera, que yo sepa, podría ser la construcción de un IQueryable < t > basado en el filtro de vaues.

        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();
            }
        }
    • Sí, pero es este el efectivo desempeño de sabio? Cuando se seleccione el ejecutado? En el final, cuando ToList() se llama? Imagine que tiene muy gran conjunto de datos….
    • No, no es un impacto en el rendimiento, ya que utiliza ejecución diferida a la consulta sólo una vez.
    • +1 Gracias por su buena respuesta.
  3. 6

    He creado un genérico repositorio que debe ayudarle. Es compatible con el uniforme de la API para consultar y ordenar en ambos conocidos y campos 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);

    Yo no sé acerca de la búsqueda del objeto/DTO usted está consiguiendo, pero usted puede crear fácilmente una búsqueda genérica objeto/DTO y se puede asignar a un objeto de Consulta en pocas líneas de código. Lo he utilizado en el pasado en torno a un servicio WCF y ha funcionado muy bien para mí.

  4. 1

    Se podía ver en la creación del servicio de uso de Servicios de Datos de WCF y crear dinámicamente la URI a la consulta de su modelo de entidad.

Dejar respuesta

Please enter your comment!
Please enter your name here