对MSSQL服务器执行存储过程时返回空数组

Empty array returned when executing stored procedure against MSSQL server

提问人:cdrrr 提问时间:10/24/2023 最后编辑:cdrrr 更新时间:11/4/2023 访问量:174

问:

我正在尝试对本地MSSQL服务器执行存储过程,但是我得到了一个被块捕获的空数组,尽管在执行时我返回了一条记录。catchSSMS

我得到的错误

System.InvalidOperationException:序列不包含任何元素 在 System.Linq.ThrowHelper.ThrowNoElementsException() 在 System.Linq.Enumerable.MaxInteger[T] (IEnumerable1 源) 在 Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression) 在 System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions (ExpressionVisitor visitor,BlockExpression 块) 在 System.Linq.Expressions.ExpressionVisitor.VisitBlock (BlockExpression 节点) 在 Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(表达式扩展表达式) 在 Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessShaper(Expression shaperExpression, RelationalCommandCache& relationalCommandCache, IReadOnlyList 1& readerColumns, LambdaExpression& relatedDataLoaders, Int32& collectionId) 在 Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQuery(ShapedQueryExpression shapedQueryExpression) 在 Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(表达式扩展表达式) 在 Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitExtension(表达式扩展表达式) 在 Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](表达式查询) 在 Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](表达式查询,布尔异步) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase 数据库、表达式查询、IModel 模型、布尔异步) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<c__DisplayClass12_01.<ExecuteAsyncb__0() 在 Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](对象缓存键,Func1 编译器) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](表达式查询,取消令牌取消令牌) 在 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](表达式表达式,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.GetAsyncEnumerator(CancellationToken cancellationToken) 在 System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable1.GetAsyncEnumerator() 在 Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 源,CancellationToken cancellationToken) 在 Project.Infrastructure.Repositories.SupplierDashboardRepository.GetORdersListAsync (String externalUID) 中 C:.path\Project.Infrastructure\Repositories\SupplierDashboardRepository.cs:line 在 C:.path\Project.Aplication\Services\Supplier\Analytics\SupplierDashboardService.cs:第 55 行中的 Project.Application.Services.Supplier.Analytics.SupplierDashboardService.GetSubscriptionsListAsync(字符串 externalUID) 在 C:.path\Project\Controllers\Supplier\Dashboard\General\SubscriptionController.cs:第 31 行中的 Project.WebApi.Controllers.Supplier.Dashboard.General.SubscriptionController.GetSubscriptionsListAsync(字符串 externalUID) at lambda_method5(闭合,对象) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, 对象控制器, Object[] 参数) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsyncg__Awaited|12_0 (ControllerActionInvoker 调用程序,ValueTask1 actionResultValueTask) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsyncg__Awaited|10_0 (ControllerActionInvoker 调用程序、 任务 lastTask、 下一个状态、 范围范围、 对象状态、 布尔值 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow (ActionExecutedContextSealed 上下文) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- 从上一个位置---结束堆栈跟踪 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsyncg__Awaited|20_0 (ResourceInvoker 调用程序、 任务 lastTask、 下一个状态、 范围范围、 对象状态、 布尔值 isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsyncg__Awaited|17_0 (ResourceInvoker 调用程序、 任务任务、 IDisposable 范围) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsyncg__Awaited|17_0 (ResourceInvoker 调用程序、 任务任务、 IDisposable 范围) 在 Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invokeg__AwaitRequestTask|6_0 (终结点终结点、任务请求任务、ILogger 记录器) 在 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) 在 Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke (HttpContext httpContext) 在 Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke (HttpContext httpContext、ISwaggerProvider swaggerProvider) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext 上下文)

HEADERS 接受:text/plain 接受编码:gzip、deflate、br 接受语言:en-US,en 连接:关闭 主机:localhost:44385 Referer: https://localhost:44385/swagger/index.html User-Agent: Mozilla/5.0 (Windows NT 10.0;Win64的;x64) AppleWebKit/537.36 (KHTML, 像 Gecko) Chrome/118.0.0.0 Safari/537.36 sec-ch-ua: “铬”;v=“118”, “勇敢”;v=“118”, “不是=A?品牌“;v=“99” sec-ch-ua-mobile:?0 sec-ch-ua-platform:“Windows” sec-gpc:1 sec-fetch-site:同源 sec-fetch-mode:cors sec-fetch-dest:空

这是我在以下方面的方法:repository

public class AnalyticsRepository : IAnalyticsRepository
{
    public AnalyticsRepository(GuacamoleContext context)
    {
        Context = context;
    }

    public async Task<List<AnalyticsOrder>> GetOrderListAsync(string externalUID)
    {
        try
        {
            var OrderList = await Context.AnalyticsOrders.FromSqlInterpolated($"EXEC usp__OrderList @externalUID = {externalUID}").ToListAsync();

            return OrderList;

        }
        catch (Exception e)
        {
            Console.WriteLine($"Error {e.Message}");
            return new List<AnalyticsOrder>();
        }
    }

    public GuacamoleContext Context { get; }

}

这是我在以下方面的方法:service

public class SupplierAnalyticsService : ISupplierAnalyticsService
{
    private readonly ISupplierAnalyticsRepository _supplierAnalyticsRepository;

    public SupplierAnalyticsService(ISupplierAnalyticsRepository supplierAnalyticsRepository)
    {
        _supplierAnalyticsRepository = supplierAnalyticsRepository;
    }


    public async Task<List<AnalyticsOrder>> GetOrdersListAsync(string externalUID)
    {
        return await _supplierAnalyticsRepository.GetOrderListAsync(externalUID);
    }
}

这是我的:controller

   public class OrdersListController : ControllerBase
    {
        private readonly ISupplierAnalyticsService _supplierAnalyticsService;

        public OrdersListController(ISupplierAnalyticsService supplierAnalyticsService)
        {
            _supplierAnalyticsService = supplierAnalyticsService;
        }

        [HttpGet("analytics/orders/list")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(StatusCodes.Status403Forbidden)]
        [ProducesResponseType(StatusCodes.Status413PayloadTooLarge)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public async Task<ActionResult<List<AnalyticsOrder>>> GetOrdersListAsync(string externalUID)
        {
            var list = await _supplierAnalyticsService.GetOrdersListAsync(externalUID);

            return Ok(list);
        }

在 DbContext 中,我添加了一个新实体,并按照此处的 Microsoft 文档将其设置为没有键:

modelBuilder.Entity<AnalyticsOrder>().HasNoKey().ToView(null);

我在这里错过了什么?为什么在执行 via Swagger 时得到一个空数组?谢谢stored procedure

SQL-Server 实体框架 .NET-Core

评论

0赞 Charlieface 10/24/2023
错误消息是什么(输出到控制台)?您的过程定义将很有用。
0赞 cdrrr 10/24/2023
@Charlieface - 编辑了我的问题
0赞 Charlieface 10/24/2023
你为什么打电话.ToView(null)
0赞 cdrrr 10/24/2023
以为我需要指定我期望回来的结构。点是没有调用返回相同的错误消息。ToView
0赞 Steve Py 10/25/2023
如果尝试直接从表中加载此实体,会发生什么情况?如果实体不表示表,而是表示此自定义存储过程的结果,则可以尝试创建视图。该问题很可能与实体定义和/或存储过程本身中的详细信息有关,其中 EF 尝试转换结果,但遇到它得到的内容和预期的僵局。

答:

0赞 cdrrr 11/4/2023 #1

所以,过了一段时间,遇到了并找到了解决方案。

最初,我在实体中设置如下:DbContext

modelBuilder.Entity<Type>().HasNoKey().ToView(null);

这是怎么回事?什么都没有,除非你想把它映射到 .要将 映射到 a,您需要使用 .viewentitystored procedure.HasNoKey().ToFunction("[dbo].[YourStoredProcedureName]")

更进一步,在每次迁移时创建一个表,尽管我专门将其设置为没有键。为了超越它,我设置了要从迁移中排除的内容。完整的代码行是:EF CoreDbContext

modelBuilder.Entity<YourType>().HasNoKey().ToFunction("[dbo].[YourStoredProcedureName]").Metadata.SetIsTableExcludedFromMigrations(true);

最后但并非最不重要的一点是,返回类型必须具有类 props。因此,请正确定义模型:

public class Model
{
    public int code { get; set; }
    public string title { get; set; }
    ....................................
}

为了确保完全理解,我还包含了从方法调用它的完全限定名称:EF Corestored procedure

public async Task<List<Type>> GetListAsync(string externalUID)
    {
        try
        {
            var xList = await Context.DbSetType
                .FromSqlInterpolated($"EXEC [dbo].[YourStoredProcedureName] @externalUID = {externalUID}")
                .ToListAsync();

            return xList;
        }
        catch (Exception e)
        {
            Console.WriteLine($"Error {e.Message}");
            return new List<Type>();
        }
}

我希望这个解决方案能为您节省一些时间!