Почему структура Entity Framework не может видеть информацию о столбце хранимой процедуры?

У меня есть следующая хранимая процедура, и когда я пытаюсь выполнить функцию Import, она говорит, что моя хранимая процедура не возвращает столбцы. Что мне не хватает? Какие-либо предложения?

Proc:

ALTER PROCEDURE [healthc].[ev_kc_Products_Search] ( @SearchString VARCHAR(1000) ) AS SET NOCOUNT ON DECLARE @SQL VARCHAR(max), @SQL1 VARCHAR(max), @Tag VARCHAR(5) CREATE TABLE #T ( ID INT, VendorName VARCHAR(255), ItemName VARCHAR(255), Type VARCHAR(2), Sequence TINYINT ) SET @SQL = ' INSERT #T SELECT VendorID ID, Name VendorName, NULL ItemName, ''V'' Type, 0 Sequence FROM tblVendors WHERE '+REPLACE(@SQL1,@Tag,'Name')+' UNION ALL BLAH BLAH BLAH' EXEC(@SQL) SELECT ID, VendorName, ItemName, Type FROM #T 

Попробуйте добавить эту строку в начало хранимой процедуры:

 SET FMTONLY OFF 

Вы можете удалить это после завершения импорта.

Что происходит здесь за кулисами?

  1. Выполняя функцию import -> Get Column Information … Visual Studio выполняет хранимый процесс со всеми значениями параметра как NULL (вы можете перекрестно проверить это через MS SQL Profiler).

  2. Выполняя шаг 1, возвращаемые столбцы сохраненного proc возвращаются с его типом данных и длиной.

  3. После получения информации о столбце нажатие кнопки «Создать новый сложный тип» создает сложный тип SP в споре.

В вашем случае хранимые параметры proc не являются нулевыми, поэтому вызов Visual Studio терпит неудачу и не возвращает столбцы.

Как справиться с этим?

 IF (1 = 0) 
 НАЧАТЬ 
     УСТАНОВИТЬ FMTONLY OFF 
     если @ param1 имеет значение null и @ param2 равен нулю, тогда
         начать
             Выбрать
             cast (null как varchar (10)) как Column1,
             cast (null как бит) как Column2,
             cast (null как десятичный) в качестве столбца3
         КОНЕЦ
 КОНЕЦ   

Если быть точным (в вашем случае):

 IF (1 = 0) 
 НАЧАТЬ 
     УСТАНОВИТЬ FMTONLY OFF 
     если @SearchString имеет значение null, тогда
         НАЧАТЬ
             Выбрать
             cast (null as int) как идентификатор,
             cast (null как varchar (255)) как VendorName,
             cast (null как varchar (255)) как ItemName,
             cast (null как varchar (2)) как Тип
         КОНЕЦ
 КОНЕЦ   

Ссылка: http://mysoftwarenotes.wordpress.com/2011/11/04/entity-framework-4-%E2%80%93-the-selected-stored-procedure-returns-no-columns-part-2/

в полноте и принятии простого ответа @benshabatnoam, просто введите следующий код в начале:

 IF (1=2) SET FMTONLY OFF 

Примечание: он работает в EF 6.1.3 и Visual Studio 2015 Update 3

У вас возникла эта проблема из-за временной таблицы. Все, что вам нужно сделать, это: 1. Измените сохраненную процедуру, чтобы вернуть выбранную statemant без таблицы temp. 2. Перейдите в функцию импорта и получите информацию о столбце. 3. Измените сохраненную процедуру на оригинал.

Как быстрый и грязный способ заставить EF найти столбцы, закомментируйте предложение where в вашем сохраненном proc (возможно, добавьте TOP 1, чтобы остановить его возrotation), добавьте proc в EF и создайте сложный тип, затем раскомментируйте где предложение снова.

Если вы используете временную таблицу, сущность Entity (EDMX) не может понять, что происходит.

Поэтому верните пустой результат с именем столбца, закомментируйте всю свою хранимую процедуру и выполните в SQL-менеджере, затем получите сложный тип в визуальной студии. После сохранения верните хранимую процедуру в исходное состояние (без рамок).

удачи/

Я хотел бы добавить что-то к ответу Sudhanshu Singh: он работает очень хорошо, но если у вас более сложные структуры, объедините его с объявлением таблицы.

Я успешно использовал следующее (поместите его в самом начале хранимой процедуры):

 CREATE PROCEDURE [EY].[MyStoredProc] AS BEGIN SET NOCOUNT ON; IF (1=0) BEGIN SET FMTONLY OFF BEGIN -- declaration + dummy query -- to allow EF obtain complex data type: DECLARE @MyStoredProcResult TABLE( ID INT, VendorName VARCHAR(255), ItemName VARCHAR(255), Type VARCHAR(2), Sequence TINYINT ); SELECT * FROM @MyStoredProcResult WHERE (1=0) END END -- your code follows here (SELECT ... FROM ...) -- this code must return the same columns/data types -- -- if you require a temp table / table variable like the one above -- anyway, add the results during processing to @MyStoredProcResult -- and then your last statement in the SP can be -- SELECT * FROM @MyStoredProcResult END 

Обратите внимание : 1=0 гарантирует, что он никогда не будет выполнен, но EF вычитает из него структуру.

После того, как вы сохранили хранимую процедуру, откройте файл EDMX в Visual Studio, обновите модель данных, перейдите в браузер модели Entity Frameworks. В браузере моделей найдите свою хранимую процедуру, откройте диалоговое окно «Редактировать функцию импорта», выберите «Возвращает коллекцию … Комплекс», затем нажмите кнопку «Получить информацию о столбцах».

Он должен отображать структуру, определенную выше. Если это так, нажмите «Создать новый сложный тип», и он создаст имя с хранимой процедурой, например «MyStoredProc_Result» (добавлено «_Result»).

Теперь вы можете выбрать его в выпадающем списке «Возвращает коллекцию … Комплекс» в том же диалоговом окне.

Всякий раз, когда вам нужно что-то обновить, сначала обновите SP, затем вы можете вернуться в диалоговое окно «Редактировать функцию импорта» и нажать кнопку «Обновить» (вам не нужно воссоздавать все с нуля).

У меня была эта проблема, мне нужно было создать тип таблицы, заданный пользователем, и вернуть ее.

 CREATE TYPE T1 AS TABLE ( ID INT, VendorName VARCHAR(255), ItemName VARCHAR(255), Type VARCHAR(2), Sequence TINYINT ); GO 

Теперь ваша хранимая процедура будет выглядеть так:

 ALTER PROCEDURE [healthc].[ev_kc_Products_Search] ( @SearchString VARCHAR(1000) ) AS SET NOCOUNT ON DECLARE @SQL VARCHAR(max), @SQL1 VARCHAR(max), @Tag VARCHAR(5) @T [schema].T1 SET @SQL = 'SELECT VendorID ID, Name VendorName, NULL ItemName, ''V'' Type, 0 Sequence FROM tblVendors WHERE '+REPLACE(@SQL1,@Tag,'Name')+' UNION ALL BLAH BLAH BLAH' INSERT INTO @T EXEC(@SQL) SELECT ID, VendorName, ItemName, Type FROM @T 

Просто добавьте инструкцию select без цитаты, выполните хранимую процедуру, перейдите к обновлению модели, отредактируйте импорт функции и получите информацию о столбцах. Это должно заполнить новые столбцы. Обновите набор результатов и вернитесь к сохраненному процессу и удалите только что добавленный список выбора. И выполните хранимую процедуру. Таким образом, ваши столбцы будут заполнены в наборе результатов. См. Ниже, где можно добавить список выбора без цитаты.

  ALTER PROCEDURE [healthc].[ev_kc_Products_Search] ( @SearchString VARCHAR(1000) ) AS SET NOCOUNT ON; SELECT VendorID ID, Name VendorName, NULL ItemName, ''V'' Type, 0 Sequence FROM tblVendors DECLARE @SQL VARCHAR(max), @SQL1 VARCHAR(max), @Tag VARCHAR(5) CREATE TABLE #T ( ID INT, VendorName VARCHAR(255), ItemName VARCHAR(255), Type VARCHAR(2), Sequence TINYINT ) 

SET @SQL = ‘

 INSERT #T SELECT VendorID ID, Name VendorName, NULL ItemName, ''V'' Type, 0 Sequence FROM tblVendors WHERE '+REPLACE(@SQL1,@Tag,'Name')+' UNION ALL BLAH BLAH BLAH' 

EXEC (@SQL)

SELECT ID, VendorName, ItemName, Type FROM #T

Надеюсь, это поможет кому-то.

  • Как вы отлаживаете хранимые процедуры MySQL?
  • Interesting Posts
    Давайте будем гением компьютера.