3

У меня есть хранимая процедура, которая возвращает 0 или 1 в зависимости от того, существует ли или нет указанный адрес электронной почты в моей базе данных:Не удается получить хранятся результаты процедуры с Entity Framework 6

CREATE PROCEDURE [DatabaseSchema].[EmailAddressIsDuplicate] (@emailAddress nvarchar(255)) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    IF EXISTS(
     SELECT * 
     FROM [DatabaseSchema].[EmailUpdatesRegistrant] 
     WHERE EmailAddress = @emailAddress 
    ) 
     RETURN 1 
    ELSE 
     RETURN 0 

    RETURN 0 
END 

GO 

И я m пытается получить результаты этой хранимой процедуры из контекста базы данных Entity Framework 6:

using (DatabaseContext dbContext = new DatabaseContext()) 
{ 
    ObjectParameter param = new ObjectParameter("emailAddress", typeof(bool)); 
    var result = dbContext.EmailAddressIsDuplicate(emailAddress); 
} 

У меня появляется много ошибок.

Ошибка №1: Используя приведенный выше код, var result всегда установлен на -1.

Ошибка № 2: Я пытался перемещаться в Edit Function Import и установить Returns a Collection Of к Boolean скаляр. Это выдает следующее сообщение об ошибке:

The data reader returned by the store data provider does not have enough columns for the query requested.

Ошибка # 3: Я вернулся и установить Edit Function Import возвращаемое значение None. Затем я попытался следующий код из этого ответа:

using (DatabaseContext dbContext = new DatabaseContext()) 
{ 
    var p = new SqlParameter("@emailAddress", emailAddress); 
    var result = dbContext.Database.SqlQuery<bool>("DatabaseSchema.EmailAddressIsDuplicate", p); 
} 

Нет немедленных ошибок, возникающих, но я понятие не имею, могу ли я вывожу полезные данные из var result. Попытка бросить result к bool бросками следующее сообщение об ошибке:

Cannot convert type 'System.Data.Entity.Infrastructure.DbRawSqlQuery' to 'bool'

Любые идеи о том, как я могу видеть результаты этой хранимой процедуры (0 или 1)?

+0

что возвращаемый тип EmailAddressIsDuplicate (EMAILADDRESS); в настоящее время? – DaniDev

ответ

1

Вы можете попробовать добавить параметр вывода (@result) в хранимая процедура подписи:

CREATE PROCEDURE [DatabaseSchema].[EmailAddressIsDuplicate] 
    (@emailAddress nvarchar(255), @result bit out) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    IF EXISTS(SELECT * 
       FROM [DatabaseSchema].[EmailUpdatesRegistrant] 
       WHERE EmailAddress = @emailAddress) 
     SET @result = 1 
    ELSE 
     SET @result = 0 

    RETURN @result 
END 
GO 

(вам придется заново определить свой EF Модель определения функции соответственно)

using (DatabaseContext dbContext = new DatabaseContext()) 
{ 
    ObjectParameter isDuplicate = new ObjectParameter("isDuplicate", typeof(bool)); 
    var result = dbContext.EmailAddressIsDuplicate(emailAddress, isDuplicate); 

    bool emailIsDuplicate = (bool)isDuplicate.Value;.  
} 

Если вы хотите, чтобы вызвать хранимую процедуру непосредственно выводимый параметр вы можете следовать этому предложению: Database.SqlQuery calling stored procedure that has multiple output parameters

+0

, если вы возвращаете целое число в любом случае, вы можете по крайней мере перенастроить rowcount из процедуры с отсутствием параметра промежуточного выхода. – vamsi

+0

I Первоначально я написал свое предложение с обратным типом бит. @alex может попробовать в обоих направлениях. – DaniDev

+1

Это в конечном итоге помогло мне найти мой ответ. Я обновил хранимую процедуру и использовал следующий код: 'ObjectParameter isDuplicate = new ObjectParameter (« isDuplicate », typeof (bool)); var result = dbContext.EmailAddressIsDuplicate (emailAddress, isDuplicate); bool emailIsDuplicate = (bool) isDuplicate.Value; '. Использование 'int retParam' вызовет ошибку времени компиляции. Пожалуйста, обновите свой ответ с помощью этого рабочего кода, и я пометю его как принятый - спасибо! – alex

0

Внесите хранимую процедуру в C# в значение с использованием параметров.

Ресурс: https://msdn.microsoft.com/en-us/library/yy6y35y8(v=vs.110).aspx

Таким образом, значения могут быть сохранены в переменной из ExecuteReader.

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

+0

Я могу вызвать хранимую процедуру с помощью 'SqlConnection', как предлагает ссылка, но я пытаюсь сделать это с помощью Entity Framework 6. – alex

+0

Является ли SqlConnection в отдельном слое из вашей модели фреймворка? После извлечения значений из SqlConnection и Reader добавьте его в свойство модели, к которой принадлежит значение. – JDavila

+0

Вам не нужна Entity Framework, чтобы открыть 'SqlConnection'. Конечно, я могу просто сделать это без Entity Framework, но основная проблема заключалась в том, что Entity Framework не играет хорошо с хранимыми процедурами. [Это] (http://stackoverflow.com/a/39417055/3474146) ответил на мой вопрос. – alex

-1

попробовать этот

CREATE PROCEDURE [DatabaseSchema].[EmailAddressIsDuplicate] (@emailAddress nvarchar(255)) 
AS 
BEGIN 

     SELECT * 
     FROM [DatabaseSchema].[EmailUpdatesRegistrant] 
     WHERE EmailAddress = @emailAddress 

    SELECT @@ROWCOUNT 

END 

GO 


using (DatabaseContext dbContext = new DatabaseContext()) 
{ 
    var result = dbContext.Database.SqlQuery<int32>("exec DatabaseSchema.EmailAddressIsDuplicate {0}", emailAddress).FirstOrDefault(); 
} 

Что-нибудь другое 0 в возвращаемое значение указывает на совпадение есть и число указывает количество совпадений

+0

Тогда 'var result' имеет тип' System.Data.Entity.Infrastructure.DbRawSqlQuery ', и' result [0] 'выдает ошибку' Невозможно применить индексирование с [] к выражению типа 'System.Data.Entity.Infrastructure.DbRawSqlQuery ' 'Что мне делать с результатом var? – alex

+0

Результатом является число, которое указывает количество совпадений, найденных в базе данных. – vamsi

+0

Нет, 'var result' является' System.Data.Entity.Infrastructure.DbRawSqlQuery '- не целое число. – alex

1

ПРИЧИНУ - конструктор шаблонов для EF (включая v6) неправильно устанавливает SP в качестве возвращая INT, содержащий счетчик строк, а не возвращаемое значение, потому что он неправильно вызывает неправильную ObjectContext.ExecuteFunction (найденную в генерируемом шаблоном классе YourDatabaseEntities, являющемся дочерним элементом DBContext).

Почему неправильный ExecuteFunction? - В результирующем наборе неправильно указано количество строк измененных строк, а не возвращаемое значение или выходные параметры, потому что он вызывает другую функцию ExecuteFunction, которая отбрасывает результаты. Пробел intellisense намека на ObjectContext.ExecuteFunction говорит: «Выполняет хранимую процедуру .... отбрасывает любые результаты, возвращаемые функцией, и возвращает количество строк, на которые повлияло выполнение« вместо обычного »Выполняет хранимую процедуру .... с указанными параметрами ".

ПОЧЕМУ -1: Я считаю, что SET NOCOUNT ON приводит к тому, что SP не возвращает результат подсчета и что функция ExecuteFunction Microsoft возвращает это как код ошибки.

SP FIXES - 1) Вы должны закомментировать SET NOCOUNT ON. 2) Вы должны изменить хранимую процедуру, чтобы выполнить команду SELECT в качестве последнего оператора вместо команды RETURN.

SOLUTION FIX - 1) После фиксации SP удалите SP из папки «Импортирование функций» и папки SP хранилища данных. 2) Перезагрузите SP в EDMX, используя «Обновить модель из базы данных». 3) Перестройте весь ваш проект данных, где находится EDMX. 4) Выйдите из Visual Studio и вернитесь. 5) Восстановить общее решение.

См: Entity Framework (Database first) has incorrect return result from stored procedure