Хранимые процедуры в EF Core 3.0

Как использовать хранимые процедуры в EF Core 3.0?

Я пробовал следующее

var user = await _context.Query<User>().FromSql("EXECUTE dbo.spGeneral_Authenticate").FirstOrDefaultAsync();

var user = await _context.Query<User>().FromSqlRaw("EXECUTE dbo.spGeneral_Authenticate").FirstOrDefaultAsync();

var user = await _context.Set<User>().FromSql("EXECUTE dbo.spGeneral_Authenticate").FirstOrDefaultAsync();

var user = await _context.Set<User>().FromSqlRaw("EXECUTE dbo.spGeneral_Authenticate").FirstOrDefaultAsync();

Ядро EF неправильно переводит SQL. Я получил переведенный SQL из файла журнала.

2019-09-27 11:21:36.086 +05:30 [Ошибка] Не удалось выполнить DbCommand ("30" мс) [Параметры=[""], CommandType='Text', CommandTimeout='30']" ""SELECT TOP(1) [u].[FullName], [u].[Пароль], [u].[Имя пользователя] FROM ( EXECUTE dbo.spGeneral_Authenticate ) AS [u]" 27 сентября 2019 г. 11:21:36.154 + 05:30 [Ошибка] Исключение при повторении результатов запроса для типа контекста "__________Context"'." ""Microsoft.Data.SqlClient.SqlException (0x80131904): неверный синтаксис рядом с ключевым словом "EXECUTE". Неверно синтаксис рядом с ')'.

Переведенный SQL:

SELECT TOP(1) [u].[FullName], [u].[Password], [u].[UserName]
FROM (
    EXECUTE dbo.spGeneral_Authenticate
) AS [u]

person Palanikumar    schedule 27.09.2019    source источник


Ответы (2)


Microsoft.Data.SqlClient.SqlException (0x80131904): неправильный синтаксис рядом с ключевым словом «EXECUTE». Неправильный синтаксис рядом с ')'.

Для вышеуказанной ошибки мы должны использовать .ToList() или .ToListAsync(), а не .FirstOrDefault() или .FirstOrDefaultAsync().

Это будет работать

var user = await _context.Set<User>().FromSql("EXECUTE dbo.spTest").ToListAsync();

это не сработает

var user = await _context.Set<User>().FromSql("EXECUTE dbo.spTest").FirstOrDefaultAsync();
/*
Transalated SQL:
SELECT TOP(1) [u].[FullName], [u].[Password], [u].[UserName]
FROM (
    EXECUTE dbo.spTest
) AS [u]
*/
person Palanikumar    schedule 30.09.2019
comment
Вы нашли способ получить только один объект с помощью необработанного sql? - person Kiran Shahi; 03.10.2019
comment
@Киран Шахи, .ToList().FirstOrDefault() - person Palanikumar; 04.10.2019
comment
ToList или ToListAsync не являются решением, они дают ту же ошибку. Что неудивительно, потому что нет никаких причин, чтобы он вел себя по-другому. На моей стороне на самом деле выполняется следующее: SELECT [u].[FullName], [u].[Password], [u].[UserName] FROM ( EXECUTE dbo.spTest ) AS [u] Итак... точно такой же пб - person Stephane; 04.10.2019
comment
@Stephane, все работает как положено, проверьте скрипт dotnetfiddle.net/XudenD - person Palanikumar; 05.10.2019
comment
код, который не может быть скопирован из моего кода. На самом деле проблема заключается в том, что у меня есть глобальная настройка фильтра запросов для этого объекта. Я заметил, что невозможно запустить какую-либо хранимую процедуру, если то, что возвращается, имеет глобальную настройку фильтра запроса или если это сущность, наследуемая от другой сущности. Я оставил вопрос на github об этом. - person Stephane; 08.10.2019
comment
@Стефан, у тебя есть ссылка на проблему, которую ты поднял? У меня та же проблема, что и у вас. - person Matt; 29.11.2019
comment
@Matt, вот он: github.com/aspnet/EntityFrameworkCore/issues/18232 - person Stephane; 03.12.2019
comment
@Kiran Shahi, var user = (await _context.Set‹User›().FromSql(EXECUTE dbo.spTest).ToListAsync()).FirstOrDefault(); - person Leo; 14.01.2020

Принятый ответ прибивает это. Вот мои два цента, однако:

Кроме того, если вы хотите получить только один результат и по-прежнему хотите, чтобы сервер вызывал асинхронно:

var user = (await _context.Set<User>().FromSql("EXECUTE dbo.spTest").ToListAsync()).FirstOrDefault();
person Leo    schedule 14.01.2020