8

У меня есть хранимая процедура в SQL Server 2008 с именем «GetPrices» с табличным параметром «StoreIDs».Таблично-оцененный параметр в хранимой процедуре и Framework Entity Framework

Это тип я создал для этого TVP:

CREATE TYPE integer_list_tbltype AS TABLE (n int) 

Я хотел бы назвать СП от моего Entity Framework. Но когда я пытаюсь добавить хранимую процедуру к EDM, я получаю следующую ошибку:

Функция GetPrices имеет параметр «StoreIDs» с параметром index 2, который имеет тип таблицы данных «тип таблицы», который не является поддерживается. Функция была исключена.

Есть ли обходной путь? Есть предположения?

Фабио

ответ

0

Вы можете проголосовать по this at microsoft connect

Update: MS не использует соединение для особенности больше. Они используют его только для отчетов об ошибках. Чтобы проголосовать за функцию EF, вам необходимо перейти на сайт EF User Voice.

Чтобы проголосовать за это конкретное issue on User Voice go here.

1

Поскольку вы не можете использовать параметр таблицы, попробуйте передать в CSV-жало и храните процедуру, которая разбивает его на строки для вас.

Существует много способов разделить строку на SQL Server. В данной статье рассматривается плюсы и минусы просто о каждом методе:

"Arrays and Lists in SQL Server 2005 and Beyond, When Table Value Parameters Do Not Cut it" by Erland Sommarskog

Вам необходимо создать раздельную функцию. Это как функция разделения может быть использовано:

SELECT 
    * 
    FROM YourTable        y 
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach to split a string in TSQL но есть множество способов, чтобы разделить строки в SQL Server, см предыдущей ссылки, объясняющие плюсы и минусы каждого из них.

Для метода Числа таблицы для работы, вы должны сделать это один раз настройки таблицы, которая будет создавать таблицу Numbers, которая содержит строки от 1 до 10000:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number 
    INTO Numbers 
    FROM sys.objects s1 
    CROSS JOIN sys.objects s2 
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number) 

После того как таблица Numbers устанавливается , создать разбитую функцию:

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 TABLE 
AS 
RETURN 
( ---------------- 
    --SINGLE QUERY-- --this will not return empty rows 
    ---------------- 
    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!='' 
); 
GO 

Теперь вы можете легко разделить строку CSV в таблицу и присоединиться на него или использовать его, как вам нужно:

CREATE PROCEDURE YourProcedure 
(
    @CSV_Param varchar(1000) 
) 
AS 

--just an example of what you can do 
UPDATE t 
    SET Col1=... 
    FROM dbo.FN_ListToTable(',',@CSV_Param) dt 
     INNER JOIN TBL_USERS     t ON CAST(dt.value AS INT)=t.id 

GO 
1

Свойство ObjectContext.Connection можно использовать для use ADO.NET для создания и использования ваших табличных параметров. Это может быть неприемлемо, но если вы хотите использовать эту замечательную функцию SQL Server 2008 и EF, это, похоже, вы только выбираете.

Затем вы можете выбрать, чтобы расширить частично сгенерированный контекст объекта с помощью метода, чтобы заботиться обо всех элементах ADO.NET низкого уровня.Например:

public partial class FriendsOnBoardEntities : ObjectContext 
{ 
    public IList<int> GetPrices(int n) 
    { 
     // 'low-level' ado.net stuff here. 
     // Use SqlParameters, SqlCommand and what not... 
    } 
} 
1

Я согласен с тем, что прохождение CSV-жало является лучшим решением в этом случае. Я хотел бы предложить более простой способ разделить строку csv, не создавая таблицы и функции, с помощью CTE:

declare @separator char(1); 
set @separator = ','; 

;with baseCte as 
(select left(@ValueList, charindex(@separator, @ValueList) - 1) as Value, 
substring(@ValueList, charindex(@separator, @ValueList) + 1, len(@ValueList)) 
as rest 
union all 
select left(rest, charindex(@separator, rest) - 1) as Value, 
substring(rest, charindex(@separator, rest) + 1, len(rest)) from baseCte 
where len(rest) > 1 
) 
select Value from baseCte 
OPTION (MAXRECURSION 0); 
Смежные вопросы