Implémentation de filtres pour l'affichage d'une table SQL sur une vue dans ASP.NET MVC (C #) et LINQ-to-SQL?

StackOverflow https://stackoverflow.com/questions/491563

Question

Un suivi de cette question , j'ai modifié mon contrôleur et mon routage afin que la valeur de tri soit maintenant attribuée à? Sort =, mais je souhaite également permettre aux utilisateurs de filtrer le tableau en fonction un ensemble de valeurs sélectionné:

Technicien: Tech1, Tech2, Tech3, etc. Catégorie: Catégorie 1, Catégorie 2, Catégorie 3, etc. Priorité: Priorité 1, Priorité 2, Priorité 3, etc.

Je n’utilise pour le moment qu’une seule table. Le moyen le plus simple d’obtenir la liste des catégories disponibles à filtrer est de sélectionner différentes valeurs de catégorie dans la table. Ils sont tous saisis via HTML, donc j’ai le contrôle de ce qui est ajouté. Je ne veux pas tous les séparer dans des tableaux différents, j’essaie de faire le maximum avec un tableau pour le moment, mais si C’est le scénario qui rompt le modèle à une table, puis je peux ajuster.

Pour clarifier le cas d'utilisation, il est probablement préférable d'afficher une capture d'écran rapide de la vue en question:

http://images.robburke.ie/stackoverflow/491563.png
Cliquez pour afficher en taille réelle.

Je souhaite implémenter un système permettant à un utilisateur de filtrer par exemple " Priority " pour afficher uniquement les problèmes pour lesquels la priorité était " Enquête.

Je recherche des suggestions sur la manière de mettre en œuvre cela à la fois au début et à la fin. J'ai essayé de trouver un site qui propose des tableaux de données similaires mais je ne peux pas en penser à l'un des mots clés de ma tête, bien que je sois certain que cette fonctionnalité a été mise en œuvre cent fois auparavant!

Quelqu'un peut-il recommander un bon moyen de le faire?

Était-ce utile?

La solution

Niveau serveur

Commençons par un pseudocode.

public ActionResult Open(string sort, string technician, 
    string category, string priority)
{
    // generate query
    // filter stuff
    // order/sort stuff
}

Il est important que l'ordre des opérations soit correct, ici. Certains fournisseurs IQueryable ( je vous regarde, Entity Framework ) ignoreront en silence les commandes si elles arrivent avant le filtrage. Commencez donc par générer une requête non ordonnée, non filtrée, comme pour votre dernière question, puis ajoutez le filtrage, puis enfin la commande.

Notez que j'ai ajouté un argument à votre action pour chaque cas de filtre possible. C'est une façon de le faire. Une autre façon de le faire serait de permettre le filtrage sur à peu près n'importe quoi, en itérant les paramètres de chaîne de requête (à l'intérieur de Request) en traitant tout ce qui n'est pas appelé & "Sort &"; comme filtre potentiel. Vous devez choisir ce qui convient le mieux à votre application.

Maintenant, comment implémentez-vous le filtrage? Ce que Marc a montré est à sens unique. Cela fonctionne vraiment bien s'il n'y a que certains cas que vous souhaitez filtrer. Évidemment, je le mettrais dans une méthode d'assistance plutôt que dans l'action elle-même. Les chances sont bonnes que vous devez réutiliser cet assistant et d'autres actions. Toutefois, si vous envisagez de proposer un filtrage sur plus de lignes que vous ne souhaitez en préciser au sein d'une même méthode, vous pouvez également utiliser la bibliothèque Microsoft Dynamic LINQ, que vous pouvez obtenir à partir de CodePlex. Cela vous permet de construire un LINQ .Where en utilisant des chaînes au lieu d’expressions lambda.

Niveau de navigateur

Maintenant que votre application peut gérer cela, vous avez besoin d'une méthode pour créer un lien qui ressemble à:

http://example.com/Issue/Open?sort = ID & Amp; priority = Investigative

Si vous disposez d'un menu d'options de filtrage, par exemple, chaque élément de menu correspond à un lien avec différents paramètres de chaîne de requête.

Ceci est un peu délicat, car vous souhaiterez probablement conserver les paramètres de chaîne de requête existants lors de l'ajout d'un nouveau. Par exemple, si un utilisateur a trié les problèmes en suspens par ID et a choisi de ne filtrer que les problèmes de priorité d'enquête, vous souhaitez néanmoins conserver le tri. Tous les liens du menu doivent donc inclure les paramètres de chaîne de requête pour la page actuellement affichée, ainsi que le paramètre de chaîne de requête pour l'élément de menu lui-même.

L’approche générale que nous adoptons en procédant ainsi est la suivante: pour chaque élément du & menu de filtrage & "; (ou quel que soit le lien de votre bâtiment):

  1. Créer un RouteValueDictionary de paramètres de chaîne de requête
  2. Ajouter tous les paramètres de chaîne de requête transmis à la vue actuelle dans le dictionnaire.
  3. Ajoutez un paramètre de chaîne de requête supplémentaire pour l'élément de menu actuel.
  4. Générez l'URL finale à l'aide de Html.RouteLink et du dictionnaire que nous avons créé.

Autres conseils

Je ne comprends pas bien le cas d'utilisation, mais vous pouvez facilement ajouter des filtres via IQueryable<T>:

var query = /* your primary query */

if(!string.IsNullOrEmpty(name)) {
    query = query.Where(row => row.Name == name);
}

if(activeOnly) {
    query = query.Where(row => row.IsActive);
}

etc.

Vous pouvez faire des choses plus sophistiquées en construisant un Expression manuellement, mais ce qui précède présente l'avantage d'être facile à déboguer et à vérifier par le compilateur (le compilateur s'assurera qu'il existe une propriété IsActive appropriée, etc.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top