C# &引用;不在「;LINQ中的条款适用于实体

C# &引用;不在「;LINQ中的条款适用于实体,c#,linq-to-entities,C#,Linq To Entities,在Linq to Entities中,我是否可以像在SQL Server中那样创建not in子句?试试: from p in db.Products where !theBadCategories.Contains(p.Category) select p; 您希望转换为Linq查询的SQL查询是什么 如果使用内存中的集合作为过滤器,最好使用Contains()的否定。请注意,如果列表太长,这可能会失败,在这种情况下,您需要选择另一种策略(请参阅下文,了解如何为完全面向数据库的查询使用策略)

在Linq to Entities中,我是否可以像在SQL Server中那样创建not in子句?

试试:

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

您希望转换为Linq查询的SQL查询是什么

如果使用内存中的集合作为过滤器,最好使用Contains()的否定。请注意,如果列表太长,这可能会失败,在这种情况下,您需要选择另一种策略(请参阅下文,了解如何为完全面向数据库的查询使用策略)


这假设一个复杂的实体,其中您根据另一个表的某些属性排除某些实体,并且需要未排除的实体的名称。如果需要整个实体,则需要将异常构造为实体类的实例,以便它们满足默认的相等运算符(请参见)。

我获取了一个列表并使用

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

注意:确保使用列表而不是Ilist,我有以下扩展方法:

    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;
    }

我以一种与SQL更相似的方式创建了它,我认为它更容易理解

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();

由于某种原因,
产生了可怕的SQL
Contains
是此处使用的方法:
myEntities.MyEntity.Select(e=>e.Name)。其中(x=>!exceptionList.Contains(x))
@GertArnold,请详细说明“生成可怕的SQL”语句好吗?我用的是Except,它很好用。没有奇怪之处,也没有性能问题。@NinjaCross上述答案中的一个语句生成带有n-1
UNION-ALL
子句的SQL,其中n是
exceptionList
中的项数。我刚刚试过EF 6.1,所以并不是说它有所改进或其他什么。在EF 4.1中是一样的,所以我不明白为什么这个答案会被接受。
包含的答案是正确的。我认为您将
Except
与另一个
IQueryable
一起使用,因此EF能够将其转换为SQL
Except
。是吗?@NinjaCross的确,这是两个
IQueryable
s和
,除了
。因此,整个表达式包含映射对象,可以转换为SQL
,除了
。使用
除了
与内存中列表不同@tvanfosson我知道,有一个解决办法:<代码>除
(具有内存列表)外,将在这些数字之前抛出“嵌套太深”。我们能否得出这样的结论:只要只涉及映射对象,
除外
就可以了,否则
包含
就更好了?@GertArnold我更新了答案以解决各种差异。当时,还有其他的答案涵盖了这个案例,我不想涉及同样的问题。既然它是旧的,并且是公认的答案,我已经把它包括进去了。它很有帮助,但不能翻译成存储表达式。没错,但我想在数据库中执行。AsEnumerable将数据加载到内存中。
    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;
    }
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));
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"));
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();