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

将SQL Server数据查询与LUIS意图关联的代码问题求助

修复你的LUIS Bot与SQL Server集成问题

先梳理下代码里的核心问题,这些就是导致无法正常运行的关键:

1. 未实现的方法调用问题

你在ContractualPowerIntent里调用的ContractualPower(context, result)方法直接抛出了NotImplementedException,而且这个方法和另一个同名的ContractualPower(object sender, EventArgs e)是完全独立的两个方法,后者根本没被调用到。

2. SQL查询的严重错误

  • 拼接SQL时,错误地把BeginDate的条件也用了EntityEAN常量,应该是EntityBeginDate
  • 直接拼接常量字符串EntityEAN而非从LUIS识别结果中获取实际的实体值,这会导致SQL语法错误
  • 直接拼接字符串存在SQL注入风险,必须改用参数化查询

3. Bot环境不适用Console操作

在Azure Web Bot里,Console.WriteLine和Console.ReadLine完全起不到和用户交互的作用,应该通过IDialogContext.PostAsync把查询结果返回给用户。

4. 异步方法的错误定义

数据库操作是异步的,你的方法应该定义为async Task而非void,否则会导致Bot上下文混乱。


修复后的完整代码示例

[Serializable]
public class BasicLuisDialog : LuisDialog<object>
{
    public BasicLuisDialog() : base(new LuisService(new LuisModelAttribute(
        ConfigurationManager.AppSettings["LuisAppId"],
        ConfigurationManager.AppSettings["LuisAPIKey"],
        domain: ConfigurationManager.AppSettings["LuisAPIHostName"])))
    {
    }

    // Constants
    public const string IntentContractualPower = "SearchContractualPower";
    public const string IntentNone = "None";
    public const string EntityEAN = "EAN";
    public const string EntityBeginDate = "BeginDate";

    // 获取识别到的实体字符串
    private string BotEntityRecognition(LuisResult result)
    {
        StringBuilder entityResults = new StringBuilder();
        if (result.Entities.Count > 0)
        {
            foreach (EntityRecommendation item in result.Entities)
            {
                entityResults.Append($"{item.Type}={item.Entity},");
            }
            // 移除最后一个逗号
            if (entityResults.Length > 0)
            {
                entityResults.Remove(entityResults.Length - 1, 1);
            }
        }
        return entityResults.ToString();
    }

    [LuisIntent(IntentContractualPower)]
    public async Task ContractualPowerIntent(IDialogContext context, LuisResult result)
    {
        await ProcessContractualPowerQuery(context, result);
    }

    private async Task ProcessContractualPowerQuery(IDialogContext context, LuisResult result)
    {
        try
        {
            // 从LUIS结果中提取实体值
            var eanEntity = result.Entities.FirstOrDefault(e => e.Type == EntityEAN);
            var beginDateEntity = result.Entities.FirstOrDefault(e => e.Type == EntityBeginDate);

            if (eanEntity == null || beginDateEntity == null)
            {
                await context.PostAsync("请提供EAN编号和起始日期,我才能帮你查询合同功率数据。");
                context.Wait(MessageReceived);
                return;
            }

            string eanValue = eanEntity.Entity;
            string beginDateValue = beginDateEntity.Entity;

            // 使用参数化查询避免SQL注入
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
            // 建议从Azure配置中读取连接字符串,而非硬编码
            builder.ConnectionString = ConfigurationManager.AppSettings["SqlConnectionString"];

            using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
            {
                await connection.OpenAsync();

                string sql = @"SELECT ErrorDescription FROM [err].[ErrorFactContractualPower]
                               WHERE EAN = @EAN AND BeginDate = @BeginDate";

                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    // 添加参数
                    command.Parameters.AddWithValue("@EAN", eanValue);
                    command.Parameters.AddWithValue("@BeginDate", beginDateValue);

                    using (SqlDataReader reader = await command.ExecuteReaderAsync())
                    {
                        if (reader.HasRows)
                        {
                            StringBuilder results = new StringBuilder("查询到的合同功率错误信息:\n");
                            while (await reader.ReadAsync())
                            {
                                results.AppendLine(reader.GetString(0));
                            }
                            await context.PostAsync(results.ToString());
                        }
                        else
                        {
                            await context.PostAsync("没有找到匹配的合同功率数据。");
                        }
                    }
                }
            }
        }
        catch (SqlException ex)
        {
            await context.PostAsync($"数据库查询出错:{ex.Message}");
        }
        catch (Exception ex)
        {
            await context.PostAsync($"发生未知错误:{ex.Message}");
        }
        context.Wait(MessageReceived);
    }

    [LuisIntent(IntentNone)]
    public async Task NoneIntent(IDialogContext context, LuisResult result)
    {
        await ShowLuisResult(context, result);
    }

    private async Task ShowLuisResult(IDialogContext context, LuisResult result)
    {
        string entities = BotEntityRecognition(result);
        string roundedScore = result.Intents[0].Score != null 
            ? Math.Round(result.Intents[0].Score.Value, 2).ToString() 
            : "0";
        await context.PostAsync($"**查询内容**: {result.Query}, **意图**: {result.Intents[0].Intent}, **置信度**: {roundedScore}. **识别到的实体**: {entities}");
        context.Wait(MessageReceived);
    }
}

额外的配置建议

  1. 连接字符串配置:在Azure Web Bot的应用设置中添加SqlConnectionString项,把你的SQL Server连接字符串放进去,不要硬编码在代码里,这样更安全且便于维护。
  2. 实体验证:添加更多的实体格式验证(比如日期格式检查),避免无效的参数传入数据库。
  3. 错误处理:可以优化错误提示,给用户更友好的指引,而不是直接抛出异常信息。

内容的提问来源于stack exchange,提问作者Adam Richier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:16:55