Linq Скомпилированное использование Запроса Содержит (Как оператор SQLs IN)

Я предпочитаю второй или третий.

Причина:

  1. Каждый элемент находится на отдельной строке
  2. Достижение конца строки для добавления нового элемента является болью в текстовом редакторе
  3. Добавить новый элемент легко
  4. С третьим вариантом иногда вы можете проверить количество элементов, выбрав эти строки. Большинство редакторов сообщит вам количество выбранных строк.
5
задан Michael La Voie 4 June 2009 в 21:31
поделиться

3 ответа

вызвать хранимую процедуру и передать CVS список значений, используя этот метод:

Перед тем, как использовать мою функцию, вам нужно настроить «вспомогательную» таблицу, вам нужно сделать это только один раз для каждой базы данных:

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

используйте эту функцию для разделения вашей строки, который не повторяется и выполняется очень быстро:

CREATE FUNCTION [dbo].[FN_ListToTable]
(
     @SplitOn              char(1)              --REQUIRED, the character to split the @List string on
    ,@List                 varchar(8000)        --REQUIRED, the list to split apart
)
RETURNS
@ParsedList table
(
    ListValue varchar(500)
)
AS
BEGIN

/**
Takes the given @List string and splits it apart based on the given @SplitOn character.
A table is returned, one row per split item, with a column name "ListValue".
This function workes for fixed or variable lenght items.
Empty and null items will not be included in the results set.


Returns a table, one row per item in the list, with a column name "ListValue"

EXAMPLE:
----------
SELECT * FROM dbo.FN_ListToTable(',','1,12,123,1234,54321,6,A,*,|||,,,,B')

    returns:
        ListValue  
        -----------
        1
        12
        123
        1234
        54321
        6
        A
        *
        |||
        B

        (10 row(s) affected)

**/



----------------
--SINGLE QUERY-- --this will not return empty rows
----------------
INSERT INTO @ParsedList
        (ListValue)
    SELECT
        ListValue
        FROM (SELECT
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
                  FROM (
                           SELECT @SplitOn + @List + @SplitOn AS List2
                       ) AS dt
                      INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
                  WHERE SUBSTRING(List2, number, 1) = @SplitOn
             ) dt2
        WHERE ListValue IS NOT NULL AND ListValue!=''



RETURN

END --Function FN_ListToTable

вы можете использовать эту функцию как таблицу в соединении:

SELECT
    Col1, COl2, Col3...
    FROM  YourTable
        INNER JOIN FN_ListToTable(',',@YourString) s ON  YourTable.ID = s.ListValue

поэтому для Linq создайте хранимую процедуру:

CREATE PROCEDURE YourProcedure (

 @param1  int
,@param2  varchar(8000) --csv list is here

) as

SELECT
    Col1, COl2, Col3...
    FROM YourTable
        INNER JOIN FN_ListToTable(',',@param2  ) s ON  YourTable.ID = s.ListValue
    WHERE Col1=@param1

go

5
ответ дан 14 December 2019 в 19:24
поделиться

Разве функция

CompiledQuery.Compile 

не должна быть

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

?

И пробовали ли вы использовать расширение для 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);

Grtz,

0
ответ дан 14 December 2019 в 19:24
поделиться

Однажды я столкнулся с той же проблемой, и я почти уверен (мне придется исследовать), что я смог решить проблему, создав класс с методом, который возвращает логическое значение, которое я затем передаю из строки данных и верну истину / ложь.

0
ответ дан 14 December 2019 в 19:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: