使用Contains的Linq编译查询(如语句中的SQLs)

使用Contains的Linq编译查询(如语句中的SQLs),linq,linq-to-sql,Linq,Linq To Sql,我正在通过将Linq转换为编译查询来加速web应用程序中的Linq到SQL查询,在转换非常简单的语句时遇到了一个问题 我想编译一个简单语句,使用以下参数从数据库中获取有效的雇员: TestParams myParams = new TestParams { ValidEmps = new int[] { 1, 2, 3 } }; CREATE TABLE Numbers (Number int NOT NULL, CONSTRAINT PK_Numbers PRIMARY K

我正在通过将Linq转换为编译查询来加速web应用程序中的Linq到SQL查询,在转换非常简单的语句时遇到了一个问题

我想编译一个简单语句,使用以下参数从数据库中获取有效的雇员:

TestParams myParams = new TestParams
{
    ValidEmps = new int[] { 1, 2, 3 }
};
CREATE TABLE Numbers
(Number int  NOT NULL,
    CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
DECLARE @x int
SET @x=0
WHILE @x<8000
BEGIN
    SET @x=@x+1
    INSERT INTO Numbers VALUES (@x)
END
以下是工作查询:

IQueryable<Employees> MySelectedEmps =
    from emps in db.Employees
    where myParams.ValidEmps.Contains(emps.EmployeeID)
    select emps;
IQueryable MySelectedEmps=
来自db员工中的EMP
其中myParams.ValidEmps.Contains(emps.EmployeeID)
选择环境管理计划;
以下是我的编译尝试:

private static Func<MyDataContext, TestParams, IQueryable<Employee>> myCompiledQuery =
    CompiledQuery.Compile((MyDataContext db, TestParams myParams) =>
        from emps in db.Employees
        where myParams.ValidEmps.Contains(emps.EmployeeID)
        select emps);
私有静态函数myCompiledQuery=
CompiledQuery.Compile((MyDataContext数据库,TestParams myParams)=>
来自db员工中的EMP
其中myParams.ValidEmps.Contains(emps.EmployeeID)
选择EMP);
此语句包含compile和build,但当我运行它时,收到以下运行时错误:

不支持的比较运算符 键入“System.Int32[]”

我还尝试用相同的错误消息传递列表和IEnumerable

我还尝试用.Any(valemp=>valemp==emps.EmployeeID)语句替换.Contains语句,但仍然出现相同的错误


是否可以使用与SQL“IN”语句等效的已编译查询?我做错了什么?

调用存储过程,并使用以下方法传入CVS值列表:

在使用my函数之前,您需要设置一个“helper”表,每个数据库只需执行一次:

TestParams myParams = new TestParams
{
    ValidEmps = new int[] { 1, 2, 3 }
};
CREATE TABLE Numbers
(Number int  NOT NULL,
    CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
DECLARE @x int
SET @x=0
WHILE @x<8000
BEGIN
    SET @x=@x+1
    INSERT INTO Numbers VALUES (@x)
END
因此,对于Linq,创建一个存储过程:

创建过程您的过程 (

) 作为

去吧,不是吗

CompiledQuery.Compile 
功能需要改进

CompiledQuery.Compile<MyDataContext, TestParams, IQueryable<Employee>>
CompiledQuery.Compile
相反

您是否尝试过使用Int32的扩展(我认为EmployeeID是Int32)和In函数

public static class Int32Extensions
{
    public static bool In(this int input, List<int> list)
    {
        if (list == null || list.Count == 0) return false;
        return list.Contains(input);
    }
}

private static Func<MyDataContext, TestParams, IQueryable<Employee>> myCompiledQuery =  
  CompiledQuery.Compile<MyDataContext, TestParams, IQueryable<Employee>>((MyDataContext db, TestParams myParams) =>
    from emps in db.Employees
    where emps.EmployeeID.In(myParams.ValidEmps)
    select emps);
公共静态类Int32Extensions
{
公共静态布尔输入(此整数输入,列表)
{
if(list==null | | list.Count==0)返回false;
返回列表。包含(输入);
}
}
私有静态函数myCompiledQuery=
CompiledQuery.Compile((MyDataContext数据库,TestParams myParams)=>
来自db员工中的EMP
EMP.EmployeeID.In(myParams.ValidEmps)的位置
选择EMP);

Grtz,

我曾经遇到过同样的问题,我非常确定(我将不得不研究)我能够通过创建一个类来解决这个问题,该类上有一个返回布尔值的方法,然后我将从数据行传递该项并返回真/假。

感谢链接。这是一个令人失望的消息,我想没有人有可行的解决方法?请尝试下面我建议的存储过程……啊,来吧!如果你有更好的解决方案或者可以告诉我这有什么问题,请投反对票。是的,只需构建充满注射剂的sql字符串,然后就可以回家了!我不知道你为什么被否决,但我很感激你的想法。我仍在寻找特定于LINQ的解决方案,但这是一个有效的解决方案。答案似乎是“这是不可能的链接”,因此此基于SP的解决方案与我们的解决方案非常接近。感谢您的解决方案KM。如果可以从用法推断泛型类型和函数的参数,那么泛型类型和函数不必总是指定它们的参数。e、 g.iqeryable Func(iqeryable源,string thing)可以称为Func(list,“thing”)返回一个仍然返回相同的iqeryable,T是列表T的任意部分。编译器在这种情况下完成了工作,这与使用var是否更具可读性或直观性的争论是一样的。
CompiledQuery.Compile<MyDataContext, TestParams, IQueryable<Employee>>
public static class Int32Extensions
{
    public static bool In(this int input, List<int> list)
    {
        if (list == null || list.Count == 0) return false;
        return list.Contains(input);
    }
}

private static Func<MyDataContext, TestParams, IQueryable<Employee>> myCompiledQuery =  
  CompiledQuery.Compile<MyDataContext, TestParams, IQueryable<Employee>>((MyDataContext db, TestParams myParams) =>
    from emps in db.Employees
    where emps.EmployeeID.In(myParams.ValidEmps)
    select emps);