3

我正在使用基于 WinForms 的 C# 工具,该工具具有附加的基于 MDF 文件的数据库。我正在尝试使用该SqlCommand.ExecuteNonQuery()方法将记录保存到此附加的 MDF 数据库中,但未保存该记录。没有错误或异常发生;唯一的问题是该记录并未实际保存。

Console.WriteLine在顶部有一个显示我正在尝试运行的查询。它的语法正确,如果我从输出窗口复制粘贴它并单独运行它,它就可以工作。

我已经正确定义了连接字符串,如下所示,它可以很好地获取记录:

public static String connectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\TestBuildDB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";

这是我用来保存记录的功能:

public static void PerformDBWriteTransaction(string inputSQLStatement)
{
    Console.WriteLine(inputSQLStatement);
    DataTable returnDataTable = new DataTable();
    SqlConnection sqlConnection = new SqlConnection();
    sqlConnection.ConnectionString = connectionString;
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = sqlConnection;
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = inputSQLStatement;
    cmd.Connection.Open();
    try
    {
        cmd.ExecuteNonQuery();
    }
    catch (SqlException ex)
    {
        errorMessages.Clear();
        errorMessages.Append("The following errors were found in the SQL statement:\n\n");

        for (int i = 0; i < ex.Errors.Count; i++)
        {
            errorMessages.Append("Index #" + i + "\n" +
                "Message: " + ex.Errors[i].Message + "\n" +
                "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
                "Source: " + ex.Errors[i].Source + "\n" +
                "Procedure: " + ex.Errors[i].Procedure + "\n");
        }
        MessageBox.Show(errorMessages.ToString());
    }
    finally
    {
        cmd.Connection.Close();
    }
}

有人可以告诉我可能是什么问题吗?我是否需要以某种方式执行“提交”?

编辑:

我找到了问题,并在下面写了一个解决方案.. 感谢所有帮助我的人:)

4

6 回答 6

8

我发现了问题!这很简单,真的很愚蠢:)..上面的代码都是正确的..是的,人们指出了优化等,但上面的代码仍然是正确的。

问题是当我将 TestDB.MDF 文件导入到我的 Visual 2010 项目中时,在项目文件夹中制作了一份副本。当您运行/调试程序时,会制作此文件的另一个副本并将其放在 \bin\Debug\ 文件夹中。在我使用的连接字符串中,我提到过:AttachDbFilename=|DataDirectory|\TestBuildDB.mdf.. 这意味着所有读/写操作都对 bin\Debug 文件夹中的副本进行。但是,我正在查看以验证是否插入记录的 TestDB.MDF 文件位于项目的文件夹中!所以基本上,有两个 MDF 文件,我将记录写入一个文件,但试图在另一个文件中找到它们:)

当您将 MDF 文件添加到 VS2010 项目中时,VS2010 默认情况下会连接到该 MDF 文件,您可以从中浏览该 MDF 文件中的内容。用于此目的的 MDF 文件是放置在项目文件夹中的文件,而不是 bin\Debug\ 文件夹中的那个。就像我之前说的,我的代码使用了 bin\Debug 文件夹中的那个:)

所以我现在所做的是从我的项目中删除了 Test.MDF 文件引用,这会删除项目文件夹中存在的副本。但是,我在 bin\Debug\ 文件夹中确实有一个 TestDB.MDF 文件的副本,我从我的应用程序中连接到该文件。如果我想在我的项目之外浏览 MDf 文件,我会使用 SQL Management Studio。这里唯一的问题是 MDF 文件在给定时间只能由一个程序使用。因此,如果我必须在我的应用程序中使用它,我必须从 SQL Management Studio 将其离线,反之亦然!

我希望这个解释可以帮助那里的人:)

于 2012-09-26T09:27:37.683 回答
3

这个问题的解决方法很简单,只需在连接字符串中给出原始 MDF 文件的完整路径,如下所示:

connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=**C:\VISUAL STUDIO 2012\PROJECTS\ENGLISHTOHINDIDICTIONARY\ENGLISHTOHINDIDICTIONARY\DICTIONARY.MDF**;Initial Catalog=Dictionary;Integrated Security=false"
        providerName="System.Data.SqlClient"

就这样,你的问题解决了。

于 2014-12-11T06:15:23.343 回答
2

我遇到了同样的挑战,我只是将数据库属性“复制到输出目录”从“始终复制”更改为“不复制”,然后将我的 database.mdf(从我的 IDE 拖放)移动到 bin\debug 文件夹中。

提示:bin 目录通常是隐藏的,使用“显示所有文件”来显示它

于 2015-04-21T07:26:32.980 回答
0

首先,您应该始终将IDisposable对象包装在 ausing中,以确保它们已正确关闭和处置(并且连接池可以完成它的工作)。其次,在修改数据时,将您的 sql 包装在事务中以保持数据完整性。

尝试以下代码,看看是否引发了任何异常。我通常不建议捕获Exception,因为它太笼统了,我会让它冒泡到调用机制并在那里处理它 - 但对于这种情况,它会向你展示任何和所有问题。我认为您的特定问题处于.Open连接阶段,因此请尝试逐步完成。

public static void PerformDBWriteTransaction(string inputSQLStatement)
{
    DataTable returnDataTable = new DataTable();

    try
    {
        using (SqlConnection sqlConnection = new SqlConnection(connectionString))
        {
            sqlConnection.Open();

            using (SqlTransaction sqlTrans = sqlConnection.BeginTransaction())
            {
                try
                {
                    using (SqlCommand cmd = new SqlCommand(inputSQLStatement, sqlConnection))
                    {
                        cmd.CommandType = CommandType.Text;
                        cmd.Transaction = sqlTrans;
                        cmd.ExecuteNonQuery();
                    }
                }
                catch (SqlException sqlEx)
                {
                    sqlTrans.Rollback();

                    throw sqlEx;
                }

                sqlTrans.Commit();
            }
        }
    }
    catch (Exception ex)
    {
        errorMessages.Clear();
        errorMessages.Append("The following errors were found in the SQL statement:\n\n");

        for (int i = 0; i < ex.Errors.Count; i++)
        {
            errorMessages.Append("Index #" + i + "\n" +
            "Message: " + ex.Errors[i].Message + "\n" +
            "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
            "Source: " + ex.Errors[i].Source + "\n" +
            "Procedure: " + ex.Errors[i].Procedure + "\n");
        }

        MessageBox.Show(errorMessages.ToString());
    }
}
于 2012-09-24T12:27:08.307 回答
0

为所有异常提供一个 catch 子句。如果除了 SqlException 之外还有其他问题,您将永远看不到它是什么,并且您的数据库将永远不会被更新。想象一下有一个 FormatException ......

还要检查 ExecuteNonQuery 的返回:它是受查询影响的行数。

于 2012-09-24T12:18:26.673 回答
-1

嗨,我正在处理图书馆数据库,当我添加学生记录时executionNonQuery 显示错误,例如打开了无效的列名页面,但保存数据不会发生。这里我给出了代码声明

public partial class add_student_info : Form
{
    SqlConnection con = new SqlConnection(@"Data Source=DESKTOP-SPT6GLG\SQLEXPRESS;Initial Catalog=library_managment;Integrated Security=True;Pooling=False");

    public add_student_info()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {

            con.Open();
            SqlCommand cmd = con.CreateCommand();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "insert into student_info values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "','" + textBox4.Text + "'," + textBox5.Text + "," + textBox6.Text + "," + textBox7.Text + ")";
            cmd.ExecuteNonQuery();
            con.Close();

            MessageBox.Show("Student recorc addedd sussfully");

        }
    }
}
于 2018-03-18T07:36:14.073 回答