Comment faire une instruction 'IN' de style SQL dans LINQ to Entities (Entity Framework) si Contains n'est pas pris en charge?

c# entity-framework linq linq-to-entities

Question

J'utilise LINQ to Entities (pas LINQ to SQL) et je ne parviens pas à créer une requête de style "IN". Voici ma requête pour le moment:

var items = db.InventoryItem
                .Include("Kind")
                .Include("PropertyValues")
                .Include("PropertyValues.KindProperty")
                .Where(itm => valueIds.Contains(itm.ID)).ToList<InventoryItem>();

Quand je fais cela cependant, l'exception suivante est levée:

LINQ to Entities ne reconnaît pas la méthode "Boolean Contains (Int64)" et cette méthode ne peut pas être traduite en expression de magasin.

Quelqu'un at-il une solution de contournement ou une autre solution pour cela?

Réponse acceptée

Vous devez soit utiliser celui-ci:

.Where(string.Format("it.ID in {0}", string.Join(",", valueIds.ToArray())));

ou construisez la partie WHERE dynamiquement, comme dans cet article.

PS - Les informations ont été mises à jour et cette réponse mise à jour comme suit pour maintenir la pertinence:

Le lien référencé contient la mise à jour suivante:

... dans EF4, nous avons ajouté la prise en charge de la méthode Contains et au moins dans ce cas spécifique des paramètres de valeur de collection . Par conséquent, ce type de code fonctionne maintenant immédiatement et il n’est pas nécessaire d’utiliser une méthode de construction d’expression supplémentaire:

var statusesToFind = new List<int> {1, 2, 3, 4};
var foos = from foo in myEntities.Foos
           where statusesToFind.Contains(foo.Status)
           select foo;

Réponse populaire

Vous pouvez utiliser la méthode Any extension de Linq pour cela dans certains cas:

var userIds = new[] { 1, 2, 3 };

from u in Users
     where userIds.Any(i => i==u.Id)
     select u;

Le SQL généré semble assez étrange dans un tel cas, mais comme beaucoup de SQL généré par Linq-to-Entities, il peut être excessivement détaillé pour un humain, mais il est rapide en pratique.

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[DisplayName] AS [DisplayName], 
FROM [dbo].[Users] AS [Extent1]
WHERE  EXISTS (SELECT 
    1 AS [C1]
    FROM  (SELECT 
        [UnionAll1].[C1] AS [C1]
        FROM  (SELECT 
            1 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        UNION ALL
            SELECT 
            2 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
    UNION ALL
        SELECT 
        3 AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable3]) AS [UnionAll2]
    WHERE [UnionAll2].[C1] = [Extent1].[Id]
)


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow