You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于HotChocolate的GraphQL中使用存储过程

在HotChocolate GraphQL中传递UserID/DB-Role到存储过程的实现方案

1. 注入用户身份信息到GraphQL请求上下文

先通过自定义请求拦截器,从HttpContext(比如JWT认证的Claims)中提取UserID和DB-Role,注入到GraphQL请求上下文:

public class CustomHttpRequestInterceptor : DefaultHttpRequestInterceptor
{
    public override ValueTask OnCreateAsync(HttpContext context,
        IRequestExecutor requestExecutor,
        IQueryRequestBuilder requestBuilder,
        CancellationToken cancellationToken)
    {
        // 根据实际认证方式获取用户信息,这里以Claims为例
        var userId = context.User.Claims.FirstOrDefault(c => c.Type == "userid")?.Value;
        var dbRole = context.User.Claims.FirstOrDefault(c => c.Type == "db-role")?.Value;

        // 将信息存入请求上下文
        requestBuilder.SetProperty("UserId", userId);
        requestBuilder.SetProperty("DbRole", dbRole);

        return base.OnCreateAsync(context, requestExecutor, requestBuilder, cancellationToken);
    }
}

然后在Program.cs中注册该拦截器:

builder.Services.AddGraphQLServer()
    .AddHttpRequestInterceptor<CustomHttpRequestInterceptor>()
    // 其他GraphQL配置(如添加查询类型、实体类型等)

2. 在解析器中获取上下文并调用存储过程

在GraphQL查询的解析器方法里,通过IResolverContext取出UserID和DB-Role,再结合Entity Framework执行存储过程:

方式一:使用EF Core的FromSqlRaw执行

public class Query
{
    public async Task<List<YourEntity>> GetFilteredDataAsync(
        [Service] YourDbContext dbContext,
        IResolverContext context)
    {
        // 从上下文提取用户信息
        var userId = context.GetProperty<string>("UserId");
        var dbRole = context.GetProperty<string>("DbRole");

        // 调用MySQL存储过程,参数化避免注入
        var data = await dbContext.YourEntity
            .FromSqlRaw("CALL YourLegacyStoredProcedure({0}, {1})", userId, dbRole)
            .ToListAsync();

        return data;
    }
}

方式二:使用SqlCommand处理复杂存储过程(如带输出参数)

public async Task<List<YourEntity>> GetFilteredDataAsync(
    [Service] YourDbContext dbContext,
    IResolverContext context)
{
    var userId = context.GetProperty<string>("UserId");
    var dbRole = context.GetProperty<string>("DbRole");

    using var command = dbContext.Database.GetDbConnection().CreateCommand();
    command.CommandText = "YourLegacyStoredProcedure";
    command.CommandType = CommandType.StoredProcedure;

    // 添加MySQL参数
    command.Parameters.Add(new MySqlParameter("@UserId", userId));
    command.Parameters.Add(new MySqlParameter("@DbRole", dbRole));

    await dbContext.Database.OpenConnectionAsync();
    using var reader = await command.ExecuteReaderAsync();

    // 手动映射查询结果到实体类
    var result = new List<YourEntity>();
    while (await reader.ReadAsync())
    {
        result.Add(new YourEntity
        {
            Id = reader.GetInt32(0),
            // 其他字段按存储过程返回结果映射
        });
    }

    return result;
}

3. 补充配置与安全校验

  • 注册查询类型和实体类型:
builder.Services.AddGraphQLServer()
    .AddHttpRequestInterceptor<CustomHttpRequestInterceptor>()
    .AddQueryType<Query>()
    .AddType<YourEntity>(); // 若需自定义字段映射,可创建YourEntityType类注册
  • 添加授权校验,确保只有合法用户能访问查询:
[Authorize]
public async Task<List<YourEntity>> GetFilteredDataAsync(...)
{
    // 实现逻辑
}

内容的提问来源于stack exchange,提问作者puneeth.c.s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:45:01