web-dev-qa-db-fra.com

Clause "NOT IN" dans LINQ to Entities

Est-il possible de créer une clause not in comme dans SQL Server dans Linq to Entities ?

45
dagda1

Si vous utilisez une collection en mémoire comme filtre, il est probablement préférable d'utiliser la négation de Contains (). Notez que cela peut échouer si la liste est trop longue, auquel cas vous devrez choisir une autre stratégie (voir ci-dessous l'utilisation d'une stratégie pour une requête entièrement orientée base de données).

   var exceptionList = new List<string> { "exception1", "exception2" };

   var query = myEntities.MyEntity
                         .Select(e => e.Name)
                         .Where(e => !exceptionList.Contains(e.Name));

Si vous excluez basé sur une autre requête de base de données en utilisant Except pourrait être un meilleur choix. (Voici un link aux extensions Set supportées dans LINQ to Entities)

   var exceptionList = myEntities.MyOtherEntity
                                 .Select(e => e.Name);

   var query = myEntities.MyEntity
                         .Select(e => e.Name)
                         .Except(exceptionList);

Cela suppose une entité complexe dans laquelle vous en excluez certaines dépend de la propriété d'une autre table et que vous souhaitez connaître le nom des entités non exclues. Si vous voulez l'entité entière, vous devrez alors construire les exceptions en tant qu'instances de la classe d'entité, de manière à ce qu'elles satisfassent à l'opérateur d'égalité par défaut (voir docs ).

90
tvanfosson

Essayer:

from p in db.Products
where !theBadCategories.Contains(p.Category)
select p;

Quelle est la requête SQL que vous souhaitez traduire en requête Linq? 

14
yfeldblum

J'ai les méthodes d'extension suivantes:

    public static bool IsIn<T>(this T keyObject, params T[] collection)
    {
        return collection.Contains(keyObject);
    }

    public static bool IsIn<T>(this T keyObject, IEnumerable<T> collection)
    {
        return collection.Contains(keyObject);
    }

    public static bool IsNotIn<T>(this T keyObject, params T[] collection)
    {
        return keyObject.IsIn(collection) == false;
    }

    public static bool IsNotIn<T>(this T keyObject, IEnumerable<T> collection)
    {
        return keyObject.IsIn(collection) == false;
    }

Usage:

var inclusionList = new List<string> { "inclusion1", "inclusion2" };
var query = myEntities.MyEntity
                     .Select(e => e.Name)
                     .Where(e => e.IsIn(inclusionList));

var exceptionList = new List<string> { "exception1", "exception2" };
var query = myEntities.MyEntity
                     .Select(e => e.Name)
                     .Where(e => e.IsNotIn(exceptionList));

Très utile également lorsque vous passez directement des valeurs:

var query = myEntities.MyEntity
                     .Select(e => e.Name)
                     .Where(e => e.IsIn("inclusion1", "inclusion2"));

var query = myEntities.MyEntity
                     .Select(e => e.Name)
                     .Where(e => e.IsNotIn("exception1", "exception2"));
6
JoanComasFdz

J'ai pris une liste et utilisé,

!MyList.Contains(table.columb.tostring())

Remarque: assurez-vous d'utiliser List et non Ilist

4
Mayank

Je l'ai créé d'une manière plus similaire au SQL, je pense qu'il est plus facile à comprendre

var list = (from a in listA.AsEnumerable()
            join b in listB.AsEnumerable() on a.id equals b.id into ab
            from c in ab.DefaultIfEmpty()
            where c != null
            select new { id = c.id, name = c.nome }).ToList();
0
Rodolfo Gaspar