【问题标题】:EF Core FromSQLRaw is not calling the database?EF Core FromSQLRaw 没有调用数据库?
【发布时间】: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


【解决方案1】:

原来我犯了一个简单的错误,未能在模型public中创建字段

虽然抛出的异常肯定不会那么明显......

我还需要在 FromSqlRaw 调用之后添加AsEnumerable() 才能工作,根据这个问题:Include with FromSqlRaw and stored procedure in EF Core 3.1

【讨论】:

    猜你喜欢
    • 2020-11-23
    • 1970-01-01
    • 2022-01-14
    • 2021-03-06
    • 2021-02-26
    • 2021-04-07
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多