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

重构插入存储过程:优化C#控制台程序并解决输入跳过问题

解决Skills输入跳过问题并优化C#数据库插入代码

作为刚接触C#两天的开发者,你的代码已经完成了核心功能,很棒!下面我会先帮你解决输入被跳过的问题,再一步步讲解代码优化的方向和原因。

一、解决Skills输入被跳过的问题

问题根源

你用Console.Read()获取statusId时踩了一个常见的坑:

  • Console.Read()只会读取输入的第一个字符的ASCII值(比如输入"1"会返回49,而不是整数1)
  • 你输入完成后按下的回车键会留在输入缓冲区里
  • 后续的Console.ReadLine()会直接读取这个空回车,导致skillsInput被自动赋值为空,看起来像是输入被跳过了

修复代码

把获取statusId的逻辑改成用Console.ReadLine(),同时添加输入验证,避免用户输入非数字内容导致程序崩溃:

Console.WriteLine("Please Enter a 1 digit Status Id");
int statusId;
// 循环直到用户输入有效的1位数字
while (!int.TryParse(Console.ReadLine(), out statusId) || statusId < 0 || statusId > 9)
{
    Console.WriteLine("Invalid input! Please enter a 1-digit integer (0-9):");
}
StatusId.Value = statusId;

二、代码效率与可读性优化建议

下面是几个符合C#最佳实践的优化点,每个点都会说明为什么要这么做:

1. 用using包裹SqlCommand

SqlCommand实现了IDisposable接口,需要手动释放资源。用using包裹可以确保命令对象在使用后自动销毁,避免资源泄漏:

using (SqlCommand testCMD = new SqlCommand("People_Insert", PubsConn))
{
    // 命令的配置和执行逻辑都放在这里
}

2. 简化参数添加逻辑

你可以合并参数的声明和配置,减少冗余代码,同时保持类型明确(尽量不用AddWithValue,它可能导致隐式类型转换错误):

// 输出参数
testCMD.Parameters.Add("@Id", SqlDbType.Int, 5).Direction = ParameterDirection.Output;

// 输入参数可以链式配置,更简洁
testCMD.Parameters.Add("@Title", SqlDbType.NVarChar, 100).Value = titleInput;
testCMD.Parameters.Add("@Bio", SqlDbType.NVarChar, 100).Value = bioInput;

3. 提取输入获取的辅助方法

重复的Console.WriteLine()和Console.ReadLine()可以封装成一个方法,减少代码重复,提升可读性:

private static string GetUserInput(string prompt)
{
    Console.WriteLine(prompt);
    return Console.ReadLine()?.Trim() ?? string.Empty; // 处理null输入,去除首尾空格
}

使用示例:

string titleInput = GetUserInput("Please Enter a Title");
string bioInput = GetUserInput("Please Enter a Bio");

4. 添加异常处理

数据库操作可能遇到各种错误(比如连接失败、存储过程执行错误),添加try-catch块可以让程序更健壮,给用户友好的错误提示:

try
{
    PubsConn.Open();
    int rowsAffected = testCMD.ExecuteNonQuery();
    Console.WriteLine($"Number of Rows: {rowsAffected}");
    Console.WriteLine($"Return Value: {Id.Value}");
}
catch (SqlException ex)
{
    Console.WriteLine($"Database error occurred: {ex.Message}");
}
catch (Exception ex)
{
    Console.WriteLine($"An error occurred: {ex.Message}");
}

5. 使用var简化变量声明

对于类型明确的变量,可以用var代替具体类型,让代码更简洁:

var titleInput = GetUserInput("Please Enter a Title");
var bioInput = GetUserInput("Please Enter a Bio");

三、优化后的完整代码

using System;
using System.Data;
using System.Data.SqlClient;

namespace TestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // 把连接字符串提取为常量,方便后续修改
            const string connectionString = "Server=.\\SQLEXPRESS;Database=PeopleDatabase;Trusted_Connection=True;";

            using (SqlConnection pubsConn = new SqlConnection(connectionString))
            using (SqlCommand testCmd = new SqlCommand("People_Insert", pubsConn))
            {
                testCmd.CommandType = CommandType.StoredProcedure;

                // 配置输出参数
                var idParam = testCmd.Parameters.Add("@Id", SqlDbType.Int, 5);
                idParam.Direction = ParameterDirection.Output;

                // 获取用户输入
                var titleInput = GetUserInput("Please Enter a Title");
                var bioInput = GetUserInput("Please Enter a Bio");
                var summaryInput = GetUserInput("Please Enter a Summary");
                var headlineInput = GetUserInput("Please Enter a Headline");
                var slugInput = GetUserInput("Please Enter a Unique Slug");
                
                // 获取并验证StatusId
                Console.WriteLine("Please Enter a 1 digit Status Id");
                int statusId;
                while (!int.TryParse(Console.ReadLine(), out statusId) || statusId < 0 || statusId > 9)
                {
                    Console.WriteLine("Invalid input! Please enter a 1-digit integer (0-9):");
                }

                var skillsInput = GetUserInput("Please Enter Skills");
                var imageInput = GetUserInput("Enter an Image Url");

                // 给输入参数赋值
                testCmd.Parameters.Add("@Title", SqlDbType.NVarChar, 100).Value = titleInput;
                testCmd.Parameters.Add("@Bio", SqlDbType.NVarChar, 100).Value = bioInput;
                testCmd.Parameters.Add("@Summary", SqlDbType.NVarChar, 100).Value = summaryInput;
                testCmd.Parameters.Add("@Headline", SqlDbType.NVarChar, 100).Value = headlineInput;
                testCmd.Parameters.Add("@Slug", SqlDbType.NVarChar, 100).Value = slugInput;
                testCmd.Parameters.Add("@StatusId", SqlDbType.Int, 3).Value = statusId;
                testCmd.Parameters.Add("@Skills", SqlDbType.NVarChar, 100).Value = skillsInput;
                testCmd.Parameters.Add("@PrimaryImage", SqlDbType.NVarChar, 100).Value = imageInput;

                try
                {
                    pubsConn.Open();
                    int rowsAffected = testCmd.ExecuteNonQuery();
                    Console.WriteLine($"Number of Rows: {rowsAffected}");
                    Console.WriteLine($"Return Value: {idParam.Value}");
                }
                catch (SqlException ex)
                {
                    Console.WriteLine($"Database error: {ex.Message}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                }
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

        /// <summary>
        /// 辅助方法:获取用户输入并处理空值
        /// </summary>
        private static string GetUserInput(string prompt)
        {
            Console.WriteLine(prompt);
            return Console.ReadLine()?.Trim() ?? string.Empty;
        }
    }
}

最后说明

  • 修复后的代码彻底解决了Skills输入被跳过的问题
  • 优化后的代码更简洁、更健壮,同时遵循了C#的资源管理和编码规范
  • 注释部分可以帮助你快速理解每段代码的作用

内容的提问来源于stack exchange,提问作者Michael Chang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:12:37