【问题标题】:SQL CE Not updating database values from windows formsSQL CE 不从 Windows 窗体更新数据库值
【发布时间】:2017-07-19 01:24:03
【问题描述】:

我正在构建一个基于库存的应用程序,该应用程序可以直接从任何 PC 运行而无需任何安装,因此我使用的是 SQL CE。在开始时,我正在检查数据库是否存在。如果不是,我将创建新数据库:

        try
        {
            string conString = "Data Source='ITM.sdf';LCID=1033;Password=ABCDEF; Encrypt = TRUE;";
            SqlCeEngine engine = new SqlCeEngine(conString);
            engine.CreateDatabase();
            return true;

        }
        catch (Exception e)
        {
            //MessageBox.Show("Database Already Present");
        }

数据库已正确创建,我也可以访问数据库来创建表。我面临的问题是 - 我正在使用代码单击按钮以 Windows 形式插入和更新记录:

         using (SqlCeConnection connection = new SqlCeConnection(DatabaseConnection.connectionstring))
        {
            connection.Open();
            String Name = NameTxt.Text.ToString();
            String Phone = PhoneTxt.Text.ToString();
            double balance = Double.Parse(BalanceTxt.Text.ToString());
            String City = CityTxt.Text.ToString();
            string sqlquery = "INSERT INTO Customers (Name,Phone,Balance,City)" + "Values(@name,@phone, @bal, @city)";
            SqlCeCommand cmd = new SqlCeCommand(sqlquery, connection);
            cmd.Parameters.AddWithValue("@name", Name);
            cmd.Parameters.AddWithValue("@phone", Phone);
            cmd.Parameters.AddWithValue("@bal", balance);
            cmd.Parameters.AddWithValue("@city", City);
            int x = cmd.ExecuteNonQuery();
            if (x > 0)
            {
                MessageBox.Show("Data Inserted");
            }
            else
            {
                MessageBox.Show("Error Occured. Cannot Insert the data");
            }
            connection.Close();
        }

更新码是

        using (SqlCeConnection connection = new SqlCeConnection(DatabaseConnection.connectionstring))
        {
            connection.Open();
            int idtoedit = select_id_edit;
            String Name = NameEditTxt.Text.ToString();
            String Phone = metroTextBox1.Text.ToString();
            String City = CityEditTxt.Text.ToString();
            string sqlquery = "Update Customers Set Name = @name, Phone = @phone,City = @city where Id = @id";
            SqlCeCommand cmd = new SqlCeCommand(sqlquery, connection);

            cmd.Parameters.AddWithValue("@name", Name);
            cmd.Parameters.AddWithValue("@phone", Phone);
            cmd.Parameters.AddWithValue("@id", idtoedit);
            cmd.Parameters.AddWithValue("@city", City);
            int x = cmd.ExecuteNonQuery();
            if (x > 0)
            {
                MessageBox.Show("Data Updated");
            }
            else
            {
                MessageBox.Show("Error Occured. Cannot Insert the data");
            }
            loadIntoGrid();
            connection.Close();
        }

每当我执行插入和更新记录的代码时 - 记录都会反映在由数据库表中的适配器填充的数据网格中。但是一旦我重新启动应用程序,值就不会出现在数据库中。百万分之一的值反映在数据库中。我无法理解这个问题背后的原因。

我参考了这些文章:

C# - ExecuteNonQuery() isn't working with SQL Server CE

Insert, Update, Delete are not applied on SQL Server CE database file for Windows Mobile

但由于我以编程方式创建数据库 - 它被直接创建到 bin/debug 目录,我无法在 Visual Studio 的解决方案资源管理器中看到它以更改复制选项

【问题讨论】:

  • 只是澄清一下,当if (x > 0)? 时更新和插入查询同时运行
  • No.. 它们是分开运行的

标签: c# sql .net winforms sql-server-ce


【解决方案1】:

您可能会使用项目中的空白副本重写您的数据库文件。

this answer。您不应将数据库存储在 bin 文件夹中,而应根据需要在 AppData 或其他文件夹中的用户或公共配置文件中找到一个位置。

连接字符串如下所示:

<connectionStrings>
    <add name="ITMContext" connectionString="data source=|DataDirectory|\ITM.sdf';LCID=1033;Password=ABCDEF; Encrypt = TRUE;" providerName="System.Data.SqlServerCe.4.0">

您应该使用在应用启动时运行的自定义代码将您的 db 文件部署到选定的位置,请参阅此 ErikEJ 博客:http://erikej.blogspot.cz/2013/11/entity-framework-6-sql-server-compact-4_25.html

private const string dbFileName = "Chinook.sdf";

private static void CreateIfNotExists(string fileName)
{
    string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
    // Set the data directory to the users %AppData% folder            
    // So the database file will be placed in:  C:\\Users\\<Username>\\AppData\\Roaming\\            
    AppDomain.CurrentDomain.SetData("DataDirectory", path);

    // Enure that the database file is present
    if (!System.IO.File.Exists(System.IO.Path.Combine(path, fileName)))
    {
        //Get path to our .exe, which also has a copy of the database file
        var exePath = System.IO.Path.GetDirectoryName(
            new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);
        //Copy the file from the .exe location to the %AppData% folder
        System.IO.File.Copy(
            System.IO.Path.Combine(exePath, fileName),
            System.IO.Path.Combine(path, fileName));
    }
}

还要检查this post

您有多种选择来改变这种行为。如果您的 sdf 文件是 项目内容的一部分,这将影响数据的方式 坚持。请记住,当您调试时,您的项目的所有输出 (包括 sdf)如果在 bin/debug 文件夹中。

  • 您可以决定不将 sdf 文件作为项目的一部分并管理文件位置运行时。

  • 如果您使用“如果更新则复制”,并且您对数据库所做的项目更改将覆盖任何运行时/调试更改。

  • 如果您使用“请勿复制”,则必须在代码中指定位置(在程序运行的位置上方两层)。

  • 如果您有“始终复制”,则在运行时所做的任何更改都会被覆盖

项目中的数据库文件在调试或不调试时可能不同。还要检查this answer。您可能正在将记录写入数据库文件的另一个副本。

【讨论】:

  • 仍然无法正常工作.. 根据您的建议。如果数据库存在于 appdata 文件夹中,我检查了应用程序的启动。如果是 - 那么我进行插入和更新语句。如果不是 - 我首先在 bin 文件夹中创建数据库,然后移动到 appdata 文件夹。我的更新和插入语句的连接字符串是: public static string connectionstring = "Data Source='|DataDirectory|/ITM.sdf';LCID=1033;Password=ABCDEF; Encrypt = TRUE;";还是同样的问题。更改会反映在运行时,但不会在应用重新启动后反映
  • 而当应用程序运行时,更新/插入的数据在那里?
  • 是的。在应用程序运行时。所有值都被更新/插入。一旦我重新启动应用程序。价值观消失了
  • 也许在启动/调试您的应用程序时观察 db 文件大小可以帮助您确定代码中的哪些位置会重写/修改 db 文件或其他什么。从发布的代码中我没有看到问题。
  • 我试过测试。我发现了两种行为。 1. 增加 40 条新记录后,数据库文件大小没有改变。 2. 添加 40 条记录后,我关闭了应用程序,即使重新启动,这 40 条记录仍然存在。我再次尝试插入 1 条新记录。出现问题,重启应用后一条记录不存在
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多