Как вернуть значения из динамической хранимой процедуры SQL в Entity Framework?

У меня есть хранимая процедура, которая выполняет некоторый динамический SQL. Я хочу использовать эту хранимую процедуру в Entity Framework 4, но когда я пытаюсь создать сложный тип, процедура не возвращает столбцов. Есть ли способ заставить его вернуть мои значения и заставить структуру сущностей получать их? Вот очень упрощенный пример того, что я хочу сделать:

CREATE PROCEDURE sp_calculatesalary(@EmployeeId as int)
begin
    declare dynsql as varachar(500)
    @dynsql='Select @Salary=Salary,@UserName=Username from employee
            where EmployeeId='+cast(@EmployeeId as varchar)+ ''
    exec(@dynsql)
    select @Salary, @UserName
end

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


person Vishal    schedule 02.07.2010    source источник
comment
Почему вы используете для этого динамический SQL?   -  person JonH    schedule 02.07.2010
comment
Это просто простой демо-кейс, или ваш динамический оператор действительно так же прост, как описано выше? В этом случае вам не понадобится динамический SQL.   -  person Frank    schedule 02.07.2010
comment
Ну... это просто простой пример... Я делаю что-то сложное... поэтому использую динамический sql... я хочу использовать его в структуре сущностей... и получать значения...   -  person Vishal    schedule 02.07.2010
comment
Можно ли обмануть Entity Framework, временно вставив фиктивный код, который возвращает результирующий набор нужного вам формата? Затем измените определение процедуры фактическим кодом.   -  person Martin Smith    schedule 02.07.2010


Ответы (7)


Возможно, вы могли бы рассмотреть параметризованный SQL, если вам нужно выполнять динамические запросы:

CREATE PROCEDURE sp_calculatesalary(@EmployeeId as int)  
as 
begin   
    declare @dynsql varchar(500)   
    declare @params nvarchar(500)
    declare @salary money
    declare @username varchar(50)
    set @dynsql='Select @sal=Salary,@usernm=Username from employee where EmployeeId=@empID'   
    set @params='@empID int, @sal money OUTPUT, @usernm varchar(50) OUTPUT'
    exec sp_executesql @dynsql, @params, @empID=@EmployeeID, @sal=@salary OUTPUT, @usernm = @username OUTPUT
    SELECT @salary, @username
end
person Anon246    schedule 02.07.2010
comment
Вот как у меня это было без скалярных значений... но структура сущностей не обнаружила, что она возвращает какие-либо столбцы.... - person Vishal; 02.07.2010
comment
Тогда, возможно, вы могли бы опубликовать немного больше информации о том, почему вам нужно делать это динамически. Обычно есть способ сделать это без динамического SQL. - person Anon246; 02.07.2010
comment
У меня есть несколько предложений where... которые добавляются к основному выбору... когда я передаю соответствующие параметры... Таким образом, используя динамический sql для создания этих предложений where... но на самом деле все, что я хочу знать, это явно возвращать значения так что ef4 распознает его... - person Vishal; 02.07.2010
comment
В этом случае приведенное выше редактирование должно дать вам то, что вы хотите. Мне просто нравится выделять передовые методы предотвращения SQL-инъекций. - person Anon246; 02.07.2010
comment
Спасибо, это сработало ... буду иметь в виду практику .. :) ).. STACKOVERFLOW ПРОСТО ПОТРЯСАЕТ!!! - person Vishal; 02.07.2010
comment
@Strommy: большое спасибо Стромми - person Mohsen; 13.08.2011

попробуй это

CREATE PROCEDURE sp_calculatesalary(@EmployeeId as int)   
AS
   DECLARE @dynsql VARCHAR(500)=' Salary,Username FROM employee WHERE EmployeeId=@empID'    
   EXEC sp_executesql @dynsql,'@empID INT',@empID=@EmployeeID
   SELECT 1 AS salary,2 AS username

Поверьте мне. Этого достаточно.

Или вы можете просто создать сложный тип на основе результата вашего запроса, а затем использовать коллекцию сложного типа в качестве результата запроса.

person Mohsen    schedule 13.08.2011
comment
Благодаря всем им это было самым быстрым и легким. Еще раз спасибо. - person coolcake; 03.11.2011

добавьте следующую строку в начало вашего SP

SET FMTONLY OFF
person Nitin S    schedule 25.09.2012

Попробуйте приведенный ниже скрипт, он работает хорошо.

BEGIN TRAN

DECLARE @Result varchar(max),@Table varchar(max),@Column varchar(max)

set @Column= 'CategoryName,CategoryID'
set @Table='Category'
set @Result= ' select ' + @Column + ' from '+@Table

exec(@Result)


ROLLBACK
person RickyRam    schedule 21.05.2014

Ну, я думаю, это то, что вы ищете:

create procedure sp_calculatesalary
    @employeeId int
as
    declare @sql nvarchar(max);
    @sql='select salary, username from employee
            where employeeId=' + cast(@employeeId as nvarchar(10));

    declare @t table (salary float, username varchar(50));
    insert into @t exec(@sql);

    select salary, username from @t;
return

это создаст общедоступный частичный класс sp_calculatesalary_Result в DAL на основе структуры сущностей.

person Opochitsky Dimitry    schedule 16.10.2016

Вы пытались дать псевдонимы своему последнему выбору:

select @Salary as Salary, @UserName as UserName
person Moose    schedule 02.07.2010

Что ж, если EF не может распознать, что должна возвращать ваша хранимая процедура, создайте свой сложный тип заранее. Вы можете создать сложный тип, щелкнув правой кнопкой мыши в любом месте модели и добавив сложный тип. Затем, когда вы импортируете хранимую процедуру, вы можете выбрать сложный тип из раскрывающегося списка.

person zeeshanhirani    schedule 06.07.2010