C# 如何处理登录失败的SQL异常

C# 如何处理登录失败的SQL异常,c#,visual-studio,C#,Visual Studio,我有一个windows窗体,它显示一个组合框,供用户选择一个地理区域,然后根据选择设置SQL连接并执行SQL命令。用户总是很有可能无法访问SQL Server。我设置了一个try/catch,并向用户显示错误消息,但我真的不想中断,我是VS C#的新手,我正在询问如何将控制传递到用户可以通过做出不同选择来调整的点 将执行传递回表单加载是否合理?如果是,我该怎么做?若否,应如何处理 private void comboBox1_SelectedIndexChanged(object sen

我有一个windows窗体,它显示一个组合框,供用户选择一个地理区域,然后根据选择设置SQL连接并执行SQL命令。用户总是很有可能无法访问SQL Server。我设置了一个try/catch,并向用户显示错误消息,但我真的不想中断,我是VS C#的新手,我正在询问如何将控制传递到用户可以通过做出不同选择来调整的点

将执行传递回表单加载是否合理?如果是,我该怎么做?若否,应如何处理

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (comboBox1.SelectedIndex > 0)
        {
            List<String> distinctTableList = AttributeMap.DistinctTablesList(comboBox1.SelectedItem.ToString());
            lbTableNames.DataSource = distinctTableList;
        }
    }

    public static List<String> DistinctTablesList(String environment)
    {
        List<String> tables = new List<string>();
        var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        AppSettingsSection appSettingSection = (AppSettingsSection)config.GetSection("cbSettings");
        SqlConnection sqlcon = new SqlConnection(appSettingSection.Settings[environment].Value);
        using (sqlcon)
        {
                        StringBuilder errorMessages = new StringBuilder();
                        using (sqlcon)
                        {
                            try
                            {
                                sqlcon.Open();
                            }
                            catch (SqlException ex)
                            {
                              MessageBox.Show(ex.Message);
                            }
                        }


public partial class frmClassBuilder : Form
{
    private List<AttributeMap> attributeMapList;
    private CacheClassFactory cacheFactory;

    public frmClassBuilder()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        List<String> environmentList = AttributeMap.EnvironmentList();
        comboBox1.DataSource = environmentList;
    }
 =============================================================
    using (sqlcon)
    {
        try
        {
            sqlcon.Open();
        }
        catch (SqlException ex)
        {
          MessageBox.Show(ex.Message);
        }
    }
private void组合框1\u SelectedIndexChanged(对象发送方,事件参数e)
{
如果(comboBox1.SelectedIndex>0)
{
List distinctTableList=AttributeMap.DistinctTablesList(comboBox1.SelectedItem.ToString());
lbTableNames.DataSource=distinctTableList;
}
}
公共静态列表DistinctTablesList(字符串环境)
{
列表表=新列表();
var config=ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
AppSettingsSection appSettingSection=(AppSettingsSection)config.GetSection(“cbSettings”);
SqlConnection sqlcon=新的SqlConnection(appSettingSection.Settings[environment].Value);
使用(sqlcon)
{
StringBuilder errorMessages=新建StringBuilder();
使用(sqlcon)
{
尝试
{
sqlcon.Open();
}
catch(SqlException-ex)
{
MessageBox.Show(例如Message);
}
}
公共部分类frmClassBuilder:表单
{
私有列表属性列表;
私人CacheClassFactory cacheFactory;
公共frmClassBuilder()
{
初始化组件();
}
私有void Form1\u加载(对象发送方、事件参数e)
{
List environmentList=AttributeMap.environmentList();
comboBox1.DataSource=环境列表;
}
=============================================================
使用(sqlcon)
{
尝试
{
sqlcon.Open();
}
catch(SqlException-ex)
{
MessageBox.Show(例如Message);
}
}

我在一个企业桌面客户端中使用了以下方法,现在仍然在使用

假设您有combobox\u SelectedIndexChanged()方法,它应该如下所示:

    public void combobox_SelectedIndexChanged()
    {
        string selectedCountry = "country"; //build actual connection string as you do now.
        string connectionString = string.Format("Data Source={0};Initial Catalog=Detrack;Integrated Security=True;", selectedCountry);
        var sqlCon = new SqlConnection(connectionString);
        using (sqlCon)
        {
            // Disable some controls
            try
            {
                sqlCon.Open();
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message);
                // Disable "OK"/"Next" button
                return;
            }
            finally
            {
                ///Enable controls
            }

            sqlCon.Close();

            // "OK"/"Next" button
        }
    }
在这个方法中,您检查连接是否可以打开, 如果不能:

  • 显示错误消息
  • 禁用允许用户继续交互的控件,直到做出正确的选择
如果可以,只需关闭连接并转到代码的下一部分,即实际使用连接的地方


您还需要向用户显示某种类型的“检查连接”消息,并在检查连接时阻止其交互。

向我们展示如何使用连接字符串实例化
sqlcon
?您说的“我真的不想中断”是什么意思?您可以在这里发挥创意,如果没有太多的区域,您可以尝试环境列表中的所有值,删除导致异常的条目,只在组合框中留下有效的环境/连接字符串供用户选择-这样它就不会中断。这看起来就像简单地在消息之后放置一个返回eBox将我带回ComboBox,它似乎运行良好。我在debug中跟踪了执行,并注意到Finally语句无论如何都会执行。我肯定没有经验认识到它在其他情况下的有用性,但在这里看不到它的必要性。感谢您的建议。在这种特殊情况下,Finally block允许启用controls(即国家/地区组合框)注销连接检查结果。您可以在catch块和connection close部分中写入“Enable controls”块两次,但“finally”只允许写入一次,因为它总是被执行。