9
votes

Comment utiliser Enums avec Dynamic Linq?

J'aimerais utiliser des énumérations dans mes requêtes dynamiques de Linq.

est-il possible, et si, comment? p>

Considérez le code ci-dessous: P>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            Room aRoom = new Room() { Name = "a Room" };
            Room bRoom = new Room() { Name = "b Room" };
            Room cRoom = new Room() { Name = "c Room" };

            House myHouse = new House
            {
                Rooms = new List<Room>(new Room[] { aRoom }),
                MainRoom = aRoom
            };
            House yourHouse = new House()
            {
                Rooms = new List<Room>(new Room[] { bRoom, cRoom }),
                MainRoom = bRoom
            };
            House donaldsHouse = new House()
            {
                Rooms = new List<Room>(new Room[] { aRoom, bRoom, cRoom }),
                MainRoom = aRoom
            };

            var houses = new List<House>(new House[] { myHouse, yourHouse, donaldsHouse });

            // MainRoom.Name = \"a Room\" and Rooms.Count = 3 or 
            // ?????????????????????????
            var aRoomsHouses = houses.AsQueryable<House>().Where("MainRoom.Type = \"RoomType.Kitchen\"");

            Console.WriteLine("aRoomsHouses count = {0}", aRoomsHouses.Count());
            Console.ReadKey();
        }
    }

    public class House
    {
        public string Address { get; set; }
        public double Area { get; set; }
        public Room MainRoom { get; set; }
        public List<Room> Rooms { get; set; }
    }

    public class Room
    {
        public double Area { get; set; }
        public string Name { get; set; }
        public RoomType Type { get; set; }
    }

    public enum RoomType
    {
        Kitchen,
        Bedroom,
        Library,
        Office
    }
}


2 commentaires

Avez-vous besoin d'utiliser Dynamic-Linq. Il peut être fait avec Standard Linq


@Dean :) J'ai besoin de linq dynamique.


5 Réponses :


1
votes

Cela devrait fonctionner

    Expression<Func<House, bool>> 
        filter = (p) => p.MainRoom.Type == RoomType.Kitchen; 
        filter = (p) => p.MainRoom.Area > 200;
        filter = (p) => p.Rooms.Sum(rs => rs.Area) > 500;
        filter = (p) => p.Address.Contains("abc");
        filter = (p) => p.Area > 200;
        ...
    var aRoomsHouses = houses.AsQueryable<House>().Where(filter);


12 commentaires

Lien statique en aucun cas ... J'ai besoin de linq dynamique, car je construisais dynamiquement le filtre basé sur la spécification du filtre utilisateur.


Je ne vois aucune raison pour laquelle vous ne pouvez pas faire les types de requêtes que vous faites avec Standard Linq, à partir de l'utilisateur.


@ADEDREW, si l'utilisateur sélectionne dans la liste déroulante "cuisine", j'ai besoin de le transformer en "roomtype.kitchen", et peut-être qu'il ne choisit pas le type de la pièce, mais la zone de chambres soit inférieure à 30m2 ... donc j'ai besoin de une question dynamique


Vous êtes coincé sur le mot "dynamique". Vous pouvez faire ce genre de requête avec Standard Linq


@Serhio: En réalité, l'extension de requête dynamique est principalement destinée au moment où le type de résultat varie (colonnes de sortie, regroupement, etc.). Si vous n'avez besoin que de changer le filtre, c'est mieux ( Way plus rapide) pour utiliser le constructeur de prédicats. Cela dit, cette réponse a manqué évidemment le point de la question.


@serhio, vous pouvez passer une action dans l'endroit où la méthode, vous pouvez vous écrire une méthode pour construire une expression pouvant être utilisée dans la méthode de filtrage


Quelque chose comme ça - Liste publique Filtre (Expression > Filtre) {Retour Houses.Assuiserisable () (Filtre) .tolist (); }


@Andrew Barber: Comme je ne peux pas prédire l'entrée de l'utilisateur, je ne peux pas utiliser Statique Linq. L'utilisateur sélectionne les propriétés à filtrer, pas moi.


@HungryMind Voir cette question pour comprendre pourquoi la requête statique n'est pas possible dans mon cas: Stackoverflow.com/q/7026855/185593


@serhio: Vous avez mal compris la nature des choses ici. Je demande beaucoup plus complexe que tout le temps à l'aide de Builder Predicate - Opérateurs Standard Linq.


@serhio, je crois comprendre que l'utilisateur sélectionnera une chambre et une zone de liste déroulante ou une zone sélectionnée et une entrée> 200, quelque chose comme ça, sur la base de la saisie de l'utilisateur, vous construirez une expression de chaîne (je ne pense pas que vous demanderez que vous demanderiez à l'utilisateur de participer à «MainProom.type =. ConsoleApplication2.roomtype.kitchen "). Le point où vous pouvez également construire une expression de filtre de construction.


@Andrew Barber: Utilisation du constructeur de prédicat Vous avez toujours des commutateurs pour chaque cas une pièce, en d'autres termes, vous avez du mal à chaque propriété et il est devenu impossible d'ajouter de nouvelles propriétés sans changements de code de commutation.



4
votes

Ceci fonctionne:

houses.AsQueryable<House>()
    .Where("MainRoom.Type = ConsoleApplication2.RoomType.Kitchen")


6 commentaires

Le premier ne fonctionne pas. "Int" introuvable comme la propriété "maison" ..., la seconde ne fonctionne pas à cause de la même raison ..., et en général, vous ne pouvez pas utiliser "==", mais "=". Je crains que vous n'ayez pas testé votre requête ...


Toutes mes excuses - vous avez tout à fait raison - j'ai écrit les deux options de la mémoire tumazy ... Je viens de tester les deux et le premier était nulle part, mais la seconde avec un signe unique fonctionne bien, donc j'ai mis à jour ma réponse à inclure celui-ci seulement.


tu as raison. Votre requête fonctionne, donc peut-être que c'est une bonne réponse. Cependant, j'ai déjà posté sur une autre :), vous vous demandez également comment le faire fonctionner Stackoverflow.com/q/7077056/185593


J'ai répondu à cet autre aussi :)


Pouvez-vous essayer de modifier cette énumération et voir si l'expression ci-dessus donne un résultat approprié? Nouveau Enum: Public Enum Roomtype {Chambre à coucher, Cuisine, // Cuisine déplacée à la deuxième position de position, bureau}


Oui, changer la commande ne cherche pas à faire de la différence. Évidemment, ce n'est pas respectueux des reflicards, mais je ne pense pas que @serhio va écrire les valeurs d'enum directement dans les celles comme celle-ci - la principale poussée de la réponse est que la référence à l'énum fonctionne aussi longtemps que C'est pleinement qualifié.



21
votes

J'ai rencontré le même problème et j'ai essayé la réponse marquée spécifiée par @steve Wilkes, mais cela n'a pas fonctionné pour moi !! Ensuite, j'ai découvert que Dynamic Linq dispose d'une documentation HTML dans le même paquet mentionné que Enums peut être spécifiée en tant que littéraux à chaîne.

houses.AsQueryable<House>().Where("MainRoom.Type = \"Kitchen\"")


1 commentaires

Merci! Aucune de ces réponses n'a été fonctionnée mais en utilisant le nom de valeur Enum comme des œuvres littérales géniales.



-1
votes

Pour ajouter un nouveau type d'énum à Dynamic Linq, vous devez ajouter le code suivant:

typeof(Enum),
typeof(T)

T : Enum type


0 commentaires

1
votes

En plus, un autre paramètre d'utilisation variante xxx


0 commentaires