Plusieurs paramètres de recherche avec LINQ
Je suis en train d'écrire ce que je pense devrait être relativement simple Formulaire Windows app. Je suis à l'aide de LINQ to SQL, mais je ne l'ai jamais utilisé avant. Nous avons une base de données SQL Server, et je suis de la création d'un front-end pour accéder à cette base de données. J'essaye de trouver le moyen le plus efficace pour rechercher plusieurs (nombre arbitraire de) paramètres de recherche.
Dans le formulaire windows, j'ai créer un dictionnaire avec chaque clé de recherche, et de sa valeur pour la recherche, et la passer dans ma méthode search (). Je suis en train d'essayer de trouver un moyen de recherche de la base de données avec chacune de ces clés et leurs valeurs associées. Voici ce que je suis en train de faire:
public IQueryable<Product> Search(Dictionary<string, string> searchParams)
{
DBDataContext dc = new DBDataContext();
var query = dc.Products;
foreach (KeyValuePair<string, string> temp in searchParams)
{
query = query.Where(x => x.(temp.Key) == temp.Value);
}
return query;
}
Je me rends compte que du point de vue syntaxique x.(temp.La clé) est incorrect, mais j'espère qu'illustre ce que je suis en train de faire. Je me demandais si il existe une autre façon d'aller sur ce que je suis en train de faire sans avoir à faire un géant de l'instruction switch (ou si/d'autre si l'arbre).
MODIFIER
Donc, j'ai révisé un peu, mais je suis toujours avoir des problèmes avec elle. Voici ce que j'ai actuellement:
public IQueryable<Product> Search(Dictionary<string, string> searchParams)
{
DBDataContext dc = new DBDataContext();
string sQuery = "";
foreach (KeyValuePair<string, string> temp in searchParams)
{
sQuery += temp.Key + "=" + temp.Value + " AND ";
}
var query = dc.Products.Where(sQuery);
return query;
}
Selon le LINQ Requête Dynamique de la Bibliothèque de l'article, cela devrait être OK. Voici l'erreur que je reçois:
Le type des arguments de la méthode 'Système.Linq.Interrogeable.Où(Système D'.Linq.IQueryable, Système.Linq.Les Expressions.L'Expression>) " ne peut pas être déduit à partir de l'utilisation. Essayez de spécifier le type des arguments explicitement.
Pas entièrement sûr de ce que vous entendez par là... pourriez-vous préciser?
Chaque clé dans le dictionnaire contient les paramètres de rechercher (et de chaque valeur des paramètres à rechercher).
Par votre dynamique du générateur de requête exemple, j'ai rajouté un edit sur le "ET" à la fin ci-dessous, qui nous l'espérons corriger pour vous.
OriginalL'auteur jnevelson | 2010-10-28
Vous devez vous connecter pour publier un commentaire.
Voici un exemple qui fonctionne (je l'ai juste testé), à l'aide de la Dynamique d'une Requête LINQ de la Bibliothèque.
Et, pour le faire absolument clair que ce code fonctionne réellement ici est la réelle SQL généré:
J'ai essayé en changeant l'ordre de la chaîne de requête query = requête.Où(chaîne de caractères.Format("{0} = {1}", keyValuePair.Valeur, keyValuePair.La clé)); et ça en jette toujours la même exception.
Dans le débogueur, il semble que peu importe l'ordre de la clé et la valeur dans le dictionnaire, DynamicLibrary toujours à la recherche contre la valeur, plutôt que de la clé.
Hmmm, c'est difficile à dire sans voir votre code. Commutation de la clé et la valeur ne va pas aider. Une stratégie est à seulement temporairement coder en dur de votre chaîne de requête dans le cas Où() pour éliminer de la chaîne de construction des erreurs, et assurez-vous qu'il fonctionne de cette façon en premier. Comme: query = requête.Où("EmployeeID = 78"); et ainsi de suite.
Aussi, vous pouvez utiliser SQL Server Profiler pour vérifier le SQL généré requête. IIRC, le VS débogueur n'est pas en mesure de vous montrer le SQL lorsque vous utilisez Dynamique.
OriginalL'auteur shaunmartin
Si le Dictionnaire n'est pas nécessaire pour une raison quelconque, je voudrais rendre votre méthode de Recherche comme suit:
Ensuite, vous devez utiliser la méthode comme suit:
Est-il une raison pour laquelle vous ne pouvez pas le faire?
[Edit: ajout de AsQueryable()]
[Edit: pour la Requête Dynamique à l'aide de cordes]
Prendre un coup d'oeil ici et voir si cela aide. Je ne l'ai pas utilisé, mais il semble que c'est ce que vous cherchez:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Personnellement, je préfère généralement le type-safe Expression> approche, car cela vous donnera le temps de compilation des erreurs...mais si les chaînes sont nécessaires, alors ressemble à la meilleure façon de le faire.
Basée sur le lien ci-dessus, vous devriez être en mesure de le faire:
[Edit: Chaîne De Construction Exemple]
Ainsi, l'un des problèmes est que votre requête sql va finir avec un ET à la fin de la chaîne, mais alors pas en état après...donc, pourrais essayer de changer pour ce...syntaxe pourrait être légèrement, mais devrait être à droite:
Cela ne fera que l'utilisation de "ET" sur les conditions après la première. Espérons que cela aide...
FYI - C'est hors-sujet, mais "pourquoi" j'ai utilisé StringBuilder est que la concaténation de chaîne de la façon dont vous avait il en résulterait la chaîne d'être détruite et une nouvelle chaîne est créé dans la mémoire 4 fois par boucle...donc changé pour un StringBuilder depuis qui permettra de créer une mémoire tampon qui peut être rempli et seulement redimensionnées lorsque nécessaire.
IEnumerable
, pasIQueryable
, de sorte que le code ne compile pas. En outre, les lignes de la base de données sera filtré dans le code C#, pas dans la base de données de la couche. Ça va être plus lent et nécessite plus de mémoire.Ajouté AsQueryable() de sorte qu'il doit compiler
Sonne comme Athari sait quelque chose à propos de l'Expression<> aspect, cependant, que je n'ai pas...donc probablement mieux d'aller avec sa réponse.
OriginalL'auteur Kevin Nelson
Au lieu d'utiliser le dictionnaire, vous pouvez utiliser cette méthode:
Vous pouvez l'utiliser comme ceci:
Vous aussi vous ne serez pas limité à des propriétés de chaîne.
Cela a toujours la même limitation inhérente que j'essaie d'éviter. J'ai encore besoin de taper explicitement la propriété p.Nom, plutôt que de le faire par générées dynamiquement en s'appuyant sur ce que les clés sont présents dans le Dictionnaire (p.[KEY] = [VALEUR]). Je ne suis en aucune manière liée ou associée à l'utilisation d'un Dictionnaire, mais cela m'a semblé être la seule méthode de stockage des clés de rechercher et de leurs valeurs.
Ok, donc le Dictionnaire a été important...j'ai ajouté un lien à ma réponse sur l'utilisation des chaînes à l'aide de MS Requête Dynamique de la Bibliothèque
C'est l'erreur que je reçois: "Erreur 1 Le type des arguments de la méthode 'Système.Linq.Interrogeable.Où<TSource>(le Système.Linq.IQueryable<TSource>, Système.Linq.Les Expressions.L'Expression<Système.Func < TSource,bool>>) " ne peut pas être déduit à partir de l'utilisation. Essayez de spécifier le type des arguments explicitement."
OriginalL'auteur Athari
avoir u essayer de mettre un seul devis pour votre chaîne?
basé sur votre boucle foreach, il va être extra " ET " à la fin de la requête
essayez plutôt ceci
OriginalL'auteur Bonshington
si vous êtes prêt à créer un dictionnaire de critères de recherche que j'ai utilisé quelque chose de proche de la démarche ci-dessous. J'ai adapté ce que je dois être plus près de l'ajustement dans la façon dont vous avez été faire les choses, j'ai aussi changé les noms des tables, afin de s'adapter à un datacontext /modèle d'objet que j'ai à ma disposition.
L'idée est de créer une assortie d'une liste de termes que votre requête prend en charge la recherche par. Puis ajouter les fonctions qui renvoient une expression qui peut ensuite être passé dans la clause where de la requête.
Il convient évidemment d'ajouter une gestion d'erreur pour les clés non valides etc.
OriginalL'auteur eoldre