[Pre-Amble]
Когда я обновил свой API с .netcore2.1 до .netcore3.1, я обнаружил, что мне нужно значительно изменить код Entity Framework.
Что я не сделал не понимаю, что у меня была ошибка в хранимой процедуре в моей удаленной базе данных, которая не была выражена в моем коде .netcore2.1.
Полученные сообщения об ошибках не указывали мне направление проверка внутри хранимой процедуры. Я оставляю окончательную форму моего вопроса на тот случай, если поиск сообщений об ошибках кому-нибудь поможет.
[Вопрос]
У меня есть следующий код для вызова хранимой процедуры, которая возвращает целое число
Код работает в модульном тесте на стороне сервера, но завершается неудачно, когда он вызывается через API или SwaggerUI
var obj = connect.Ints.FromSqlInterpolated<intDto>(@$"Set NOCOUNT ON
declare @num int
exec @num = spGetDefaultID {userName}
select @num as num").ToList();
id = (int)obj.First().num;
Где connect - это мой DbContext, содержащий
public DbSet<intDto> Ints { get; set; } // I actually don't want a table
с
public class intDto
{
public int num { get; set; }
}
Я следовал совету создать фиктивное представление , чтобы я не получил нежелательную таблицу в моей базе данных.
и имел
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<intDto>).HasNoKey().ToView("view_name_that_doesnt_exist");
Стек вызовов:
System.InvalidOperationException: The required column 'num' was not present in the results of a 'FromSql' operation.
at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeFields()
at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.Initialize(DbDataReader reader, IReadOnlyList`1 columns)
at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.Initialize(IReadOnlyList`1 columns)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementation[TState,TResult](Func`3 operation, Func`3 verifySucceeded, TState state)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at MyAPi.Job_Management.JobDataRead.GetCartIdForUser(ApiDbContext connect, String userName)
Примечание. Я сильно отредактировал этот вопрос, потому что в какой-то момент у меня работал API, но больше не работал.
Я обнаружил, что мне нужно используйте .ToList (), или я получил ошибку
System.InvalidOperationException: FromSqlRaw или FromSqlInterpolated был вызван с несложным SQL и с запросом, составляющим его. Рассмотрите возможность вызова AsEnumerable
после метода FromSqlRaw или FromSqlInterpolated для выполнения композиции на стороне клиента.
[Update]
Я вставил следующий код, и он не вышел из строя
var obj = db.Ints.FromSqlInterpolated(@$"Set NOCOUNT on
select count(*) as num from people
where email like {name} ").ToList();
поэтому следующим шагом будет попытка создать новую хранимую процедуру
В качестве альтернативы, возможно, это версия базы данных ..
Интересно, что модульный тест не пройдёт, если у меня нет
Microsoft.EntityFrameworkCore.Relational.dll
упоминается в тестируемом проекте. Хотя я не использую это явно.
Сообщение об ошибке в этом сценарии:
System.MissingMethodException: 'Method not found:'System.Linq.IQueriable '1<!!O>
Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.
FromSqlInterpolated(Microsoft.EntityFrameworkCOre.DbSet'1<!!0>,
System.FormattableString)'
Я попытался изменить свой код на
var obj = connect.Ints.FromSqlInterpolated<intDto>(@$"declare @num int
exec @num = spGetDefaultID {userName}").ToList();
Но мой модульный тест выдал ошибку
The underlying reader doesn't have as many fields as expected
[Обновить]
Удаленная хранимая процедура возвращает данные с использованием набора результатов.
create PROCEDURE [dbo].[spGetDefaultID]
@email varchar(300)
AS
BEGIN
SET NOCOUNT ON;
declare @cartID int
select @CartID= id from people where email = @email /* simplified */
select @CartID /* this line was not present in my local database */
return @CartID
END