【发布时间】:2020-02-10 23:57:16
【问题描述】:
我需要重写旧的 Web 服务,因为支持旧 Web 服务的团队不再希望用他们的新工具来支持它。所以我正在使用 ASP.NET Core WebAPI 和 EF Core 3.1 重写它。
服务的大部分逻辑都停留在多年前编写的存储过程中。没有什么超级复杂的,但不要真的认为开始重写所有内容是个好主意。
问题是 EF Core 对存储过程的支持似乎充其量是缺乏的。我有一个使用 Database.ExecuteSqlRaw 将结果作为输出参数返回的工作,但是我在另一个将结果作为数据集返回的问题上遇到了麻烦。 (实际上是两个,但我们不要超前……我已经评论了它,所以它现在只返回一个。)
.FromSqlRaw 查询的(当前)问题是,当我在 XEvent Profiler 中观察它时,它似乎根本没有查询数据库。 (SQL Server 2016。)
这是我用来调用 proc 的代码:
var bundle_id = new SqlParameter("bundle_id", bundleID) { Direction = ParameterDirection.Input };
var result = this.BundleUserGuideDetails.FromSqlRaw("EXEC dbo.p_fetch_user_guide_details @bundle_id", bundle_id);
var deets = result.FirstOrDefault<BundleUserGuideDetail>();
我确实在 DBContext 类中为它创建了一个 DBSet:
public DbSet<BundleUserGuideDetail> BundleUserGuideDetails { get; set; }
由于它是无钥匙类型,因此我根据 Microsoft 的无钥匙实体指南得到了这个:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<BundleUserGuideDetail>(eb =>
{
eb.HasNoKey();
});
}
我创建的模型也具有与返回的数据相同的字段名称。
那么为什么数据库甚至没有被调用呢?
编辑:忘了写对 FirstOrDefault 的调用正在抛出“System.InvalidOperationException: 'Sequence contains no elements'”
编辑:这是完整的异常文本:
System.InvalidOperationException: Sequence contains no elements
at System.Linq.ThrowHelper.ThrowNoElementsException()
at System.Linq.Enumerable.Aggregate[TSource](IEnumerable`1 source, Func`3 func)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.ProcessEntityShaper(EntityShaperExpression entityShaperExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.VisitExtension(Expression extensionExpression)
at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.Inject(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.InjectEntityMaterializers(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at MandTBank.BBFB.BPS.BPSWebAPI.Data.BundleSystemContext.FetchUserGuideDetails(String bundleID) in C:\Users\tdevmcr\Source\Workspaces\BBFB\NeedsAssessmentSystem\Main\Sourcecode\BBFB NAS - I3 - BundleUserGuide Service\MandTBank.BBFB.BPS.BPSWebAPI\Data\BundleSystemContext.cs:line 65
【问题讨论】:
-
Forgot to write that the call to FirstOrDefault is throwing所以它正在调用数据库,但没有返回任何内容。你测试过这个存储过程吗?它是否返回具有特定@bundle_id值的任何结果? -
如果没有结果,@PanagiotisKanavos FirstOrDefault 将返回 null。它没有击中数据库。是的,我已经使用该 bundle_id 值测试了存储过程,它返回了结果......
-
发布完整的异常文本,由
Exception.ToString()生成。这包含嵌套异常和显示异常发生位置的堆栈跟踪。 有一点是确定的——查询被执行了。实际执行查询的是FirstOrDefault,而不是FromSqlRaw -
@PanagiotisKanavos 添加了异常文本。我认为在实际尝试执行查询之前尝试构建查询时它实际上崩溃了。同样,我在 XEvent Profiler 中没有看到查询命中数据库...当它执行时,我确实看到了另一个存储的过程。
标签: asp.net-core-webapi ef-core-3.1