Opérateur "IN" à Linq
Je suis en train de convertir un vieux crus de la requête Sql dans Linq avec Entity Framework ici.
Il a été à l'aide de l'opérateur avec une collection d'éléments. La requête a été quelque chose comme ça:
SELECT Members.Name
FROM Members
WHERE Members.ID IN ( SELECT DISTINCT ManufacturerID FROM Products WHERE Active = 1)
ORDER BY Members.Name ASC
Depuis le retour de la sous-requête n'est pas une chaîne unique, mais un ensemble de cordes, je ne peux pas utiliser le String.Contains()
méthode.
J'ai pensé à faire quelque chose comme :
var activeProducts = (
from products in db.ProductSet
where product.Active == true
select product.ManufacturerID);
et puis
var activeMembers = (
from member in db.ContactSet
where member.ID.ToString().Contains(activeProducts));
mais il s'arrête à l'contient en disant qu'il a des arguments non valides ... je ne peux pas sélectionner activeProducts.ManufacturerID parce qu'évidemment la convenance n'est pas là, puisqu'il revient un IQueryable...
La ligne de fond de ce que j'essaie de faire ici est de retourner une liste des membres qui ont au moins un produit actif.
Tout soupçon ?
[modifier]
Voici la requête complète de code ... j'ai essayé avec le contient sur la seconde expression, Linq ne semble pas aimer ça :
Server Error in '/' Application.
LINQ to Entities does not recognize the method 'Boolean Contains[String](System.Linq.IQueryable``1[System.String], System.String)' method, and this method cannot be translated into a store expression.
var activeProduct =(from product in Master.DataContext.ProductSet
where product.Active == true
&& product.ShowOnWebSite == true
&& product.AvailableDate <= DateTime.Today
&& ( product.DiscontinuationDate == null || product.DiscontinuationDate >= DateTime.Today )
select product.ManufacturerID.ToString() );
var activeArtists = from artist in Master.DataContext.ContactSet
where activeProduct.Contains(artist.ID.ToString())
select artist;
NumberOfArtists = activeArtists.Count();
artistsRepeater.DataSource = activeArtists;
artistsRepeater.DataBind();
[Plus de détails]
ManufacturerID est nullable GUID apparemment...
Pour une raison quelconque, le ContactSet classe ne contient aucune référence à des produits, je suppose que je vais devoir faire une requête de jointure, aucun indice ici.
source d'informationauteur Erick
Vous devez vous connecter pour publier un commentaire.
Essayer
where activeProducts.Contains(member.ID)
.MODIFIER: Avez-vous l'essayer sans
ToString
s?Vous pouvez le faire en une seule requête:
ou
Essayez la solution posté par Colin Doux à: http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0/. Il a travaillé pour moi.
Quoi à ce sujet:
vous pouvez la chaîne de n'importe quel nombre de conditions requises dans la clause where à l'aide de &&
Cendres..
Au lieu de cela:
Essayez ceci:
Que si vous remplacez la déclaration (non testé)?
Comment à ce sujet...
Aide ou de l'extension de la méthode fonctionnera très bien lors de l'interrogation d'objets en mémoire. Mais à l'encontre d'une base de données SQL, votre LINQ code sera compilé dans une arborescence d'expression, analysé et traduit dans une commande SQL. Cette fonctionnalité n'a pas de concept de la coutume-de l'extension des méthodes ou des méthodes d'autres objets comme des
.Contains(...)
.Il pourrait être facilement mis en œuvre dans la norme de LINQ-to-SQL de la fonctionnalité de Microsoft. Mais tant qu'ils ne veulent pas, nous sommes impuissants tant qu'il n'est pas open source fonctionnalité.
Tout ce que vous pouvez faire est de créer votre propre QueryProvider qui va à l'encontre d'une base de données SQL. Mais il sera difficile et c'est uniquement pour que l'on
in
caractéristique à elle seule que vous êtes absent.Toutefois, si vous voulez vraiment aller dans cette voie, amusez-vous: LINQ: LA CONSTRUCTION D'UN IQUERYABLE FOURNISSEUR DE LA SÉRIE
Enfin j'ai réussi à coder quelque chose de vraiment moche, mais qui fonctionne réellement! (lol)
J'ai déjà posté au sujet de la même à
http://www.codeproject.com/Tips/336253/Filtering-records-from-List-based-similar-to-Sql-I
Sans connaître précisément les mappages il est difficile de dire ce qui peut être fait et ce qui ne le peuvent pas. Je suppose qu'il n'y a pas de casting impliqués. Tout d'abord, vous devez vous rappeler que tout dans l'Expression Linq arbre doit avoir un équivalent en SQL. Comme certains l'ont noté, vous disposez d'un objet.ToString() dans votre Linq Consolidés.
Cependant, il semble que ce que les gens ont négligé de mentionner, c'est que vous avez DEUX usages de l'objet.ToSting(), qui doit être retiré.
Je voudrais aussi faire une variable supplémentaire pour changer la fermeture du type de capture être explicitement de DataContext (depuis le Linq déclaration est comme un lambda, et un retard évalué. Il sera nécessaire de prendre la totalité de la Maîtrise de la variable. Plus tôt, j'ai dit que tout dans votre Linq doit avoir un équivalent en SQL. Étant donné que le Maître ne peut pas exister en SQL, il n'y a pas de propriété DataContext/colonne/cartographie pour le type de Master).
J'espère que ces modifications travailler pour vous.
Dans de nombreux cas, des problèmes avec Linq to Orm peut être retracée à votre Expression Linq la capture d'un non primative (DateTime, int, string, etc) et non de l'ORM en fonction de la classe (DataContext/EntityObject etc). Les autres grandes gotcha est l'utilisation de fonctions et d'opérateurs qui ne sont pas exposés par l'ORM (il est possible de déterminer des fonctions définies par l'utilisateur .net tout au long de la moraine d'oak ridges, mais je ne le recommanderais pas en raison de l'indexation).