0

我的应用程序是一个依赖数据库的 winform 应用程序。在应用程序启动时,它连接到服务器上的 SQL 数据库,并将此信息放在 DataSet/DataTable 中。

如果由于某种原因无法访问服务器上的数据库,则应用程序具有内置的故障转移功能,它将从本地数据库中获取其信息。

如果在正常情况下,我启动将从 sql 数据库中读取的工具,并且如果它已在服务器上更新(一个单独的片段检查这一点),它应该确保本地数据库是最新的,这就是问题开始了..(见下文)

这部分工作正常并作为上下文添加 - 这是我们连接到 SQL 数据库的地方

    public static DataSet dtsTableContents;
    public static DataTable CreateDatabaseSQLConnection()
    {
        try
        {
            string strSqlConnectionString = "Data Source=MyLocation;Initial Catalog=MyCatalog;User=MyUser;Password=MyPassword;";
            SqlCommand scoCommand = new SqlCommand();
            scoCommand.Connection = new SqlConnection(strSqlConnectionString);
            scoCommand.Connection.Open();
            string strQueryToTable = "SELECT * FROM " + strTableName;
            dtsTableContents = new DataSet();
            SqlCommand scmTableInformation = new SqlCommand(strQueryToTable, scnConnectionToDatabase);
            SqlDataAdapter sdaTableInformation = new SqlDataAdapter(scmTableInformation);
            scnConnectionToDatabase.Open();
            sdaTableInformation.Fill(dtsTableContents, strTableName);
            DataTable dttTableInformation = dtsTableContents.Tables[strTableName];
            scnConnectionToDatabase.Close();
            return dttTableInformation;
        }
        catch
        {
            return null;
        }
    }

这个片段是从我的本地数据库读取的故障转移方法的一部分......

这部分工作正常并作为上下文添加 - 这是我们连接到 MDB 数据库的地方

public static DataTable CreateDatabaseConnection()
    {
        try
        {
            string ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=MyLocation;Persist Security Info=True;JET OLEDB:Database Password=MyPassword;"
            odcConnection = new OleDbConnection(ConnectionString);
            odcConnection.Open();
            string strQueryToTable = "SELECT * FROM " + strTableName;
            DataSet dtsTableContents = new DataSet();
            OleDbCommand ocmTableInformation = new OleDbCommand(strQueryToTable, ocnConnectionToDatabase);
            OleDbDataAdapter odaTableInformation = new OleDbDataAdapter(ocmTableInformation);
            ocnConnectionToDatabase.Open();
            odaTableInformation.Fill(dtsTableContents, strTableName);
            DataTable dttTableInformation = dtsTableContents.Tables[strTableName];
            ocnConnectionToDatabase.Close();
            return dttTableInformation;
        }
        catch
        {
            return null;
        }
    }

从我的 CreateDatabaseSQLConnection() 我有一个数据集。验证此 DataSet 包含来自服务器数据库的所有信息。现在我一直在谷歌搜索,发现自己试图使用这段代码来更新基于这篇文章的本地数据库:http: //msdn.microsoft.com/en-us/library/system.data.common.dataadapter.update( v=vs.71).aspx

public static void UpdateLocalDatabase(string strTableName)
    {
        try
        {
            if (CreateDatabaseConnection() != null)
            {
                string strQueryToTable = "SELECT * FROM " + strTableName;
                OleDbDataAdapter odaTableInformation = new OleDbDataAdapter();
                odaTableInformation.SelectCommand = new OleDbCommand(strQueryToTable, odcConnection);
                OleDbCommandBuilder ocbCommand = new OleDbCommandBuilder(odaTableInformation);
                odcConnection.Open();
                odaTableInformation.Update(dtsTableContents, strTableName);
                odcConnection.Close();
            }
        }
        catch { }
    }

这个片段运行没有错误,但它似乎没有改变任何东西。运行此步骤所需的时间也需要几毫秒,我认为这需要更长的时间。

我正在使用从我的 SQL 连接获得的数据集,我试图将这个数据集写入我的本地数据库。

可能是因为这是一个来自 SQL 连接的 DataSet 并且我无法通过我的 OleDbAdapter 将它写入我的 mdb 连接,还是我只是在这里错过了显而易见的事情?

任何帮助表示赞赏。

谢谢,

凯文

4

3 回答 3

1

用于从外部数据库直接备份到内部备份

我刚刚搞砸了一个 sdf 和一个基于服务器的 sql 数据库,它已经工作了。这绝不是成品,但对于一列,我有程序从外部数据库读取然后直接写在大约 15 行代码中远离本地 .sdf

            SqlConnection sqlCon = new SqlConnection( ExternalDatabaseConnectionString );
            SqlCeConnection sqlCECon = new SqlCeConnection( BackUpConnectionString );
            using ( sqlCon )
                {
                using ( sqlCECon )

                    {
                    sqlCon.Open( );
                    sqlCECon.Open( );
                    SqlCommand get = new SqlCommand( "Select * from [TableToRead]", sqlCon );
                    SqlCeCommand save = new SqlCeCommand( "Update [BackUpTable] set InfoColumn = @info where ID = @id", sqlCECon );
                    SqlDataReader reader = get.ExecuteReader( );
                    if ( reader.HasRows )
                        {
                        reader.Read( );
save.Parameters.AddWithValue("@id", reader.GetString(0));
                            save.Parameters.AddWithValue( "@info", reader.GetString( 1 ));
                            save.ExecuteNonQuery( );
                            }
                        }
                    }

对于数据库的一行,备份一列,它可以工作,我假设你会有某种自动递增的键,比如 ID?

于 2012-06-08T14:59:15.520 回答
0

我认为第一步是减少对static方法和领域的依赖。

如果您查看您的UpdateLocalDatabase方法,您会看到您正在传递strTableName该方法使用的哪个,但UpdateLocalDatabase调用 ( CreateDatabaseConnection) 的方法引用了一个名为相同的不同全局静态变量。这两个strTableName变量很可能包含不同的值,并且您没有看到它们不是同一个变量。

此外,您正在尝试写出全局静态数据集dtsTableContentsUpdateLocalDatabase但如果您再查看CreateDatabaseConnection它实际上会创建该变量的本地版本——同样,您有两个变量命名相同,其中一个是全局的,一个是本地的。

我怀疑是两个变量dtsTableContents的问题。

同样,我的建议是不要使用任何静态方法或变量,并且对于您在这里所做的事情,尽量不要使用任何全局变量。此外,重构和/或重命名您的方法以匹配更多他们实际在做的事情。

于 2012-05-28T16:48:00.687 回答
0

在无休止地尝试使用 DataAdapter.Update(Method) 之后,我放弃了。我决定使用 sdf 文件而不是 mdb。

如果我需要更新我的数据库,我删除本地数据库,创建一个新的,使用相同的连接字符串。然后我遍历数据集中的表,从中读取列名和类型,并基于此创建表。

在此之后,我遍历我的数据集并插入我用来自服务器的信息填充的数据集的内容。下面是代码,这只是“快速而肮脏”的概念证明,但它适用于我的场景。

public static void RemoveAndCreateLocalDb(string strLocalDbLocation)
    {
        try
        {
            if (File.Exists(strLocalDbLocation))
            {
                File.Delete(strLocalDbLocation);
            }
            SqlCeEngine sceEngine = new SqlCeEngine(@"Data Source= " + strLocalDbLocation + ";Persist Security Info=True;Password=MyPass");
            sceEngine.CreateDatabase();
        }
        catch
        { }
    }

public static void UpdateLocalDatabase(String strTableName, DataTable dttTable)
    {
        try
        {

            // Opening the Connection
            sceConnection = CreateDatabaseSQLCEConnection();
            sceConnection.Open();

            // Creating tables in sdf file - checking headers and types and adding them to a query
            StringBuilder stbSqlGetHeaders = new StringBuilder();
            stbSqlGetHeaders.Append("create table " + strTableName + " (");
            int z = 0;
            foreach (DataColumn col in dttTable.Columns)
            {
                if (z != 0) stbSqlGetHeaders.Append(", "); ;
                String strName = col.ColumnName;
                String strType = col.DataType.ToString();
                if (strType.Equals("")) throw new ArgumentException("DataType Empty");
                if (strType.Equals("System.Int32")) strType = "int";
                if (strType.Equals("System.String")) strType = "nvarchar (100)";
                if (strType.Equals("System.Boolean")) strType = "nvarchar (15)";
                if (strType.Equals("System.DateTime")) strType = "datetime";
                if (strType.Equals("System.Byte[]")) strType = "nvarchar (100)";

                stbSqlGetHeaders.Append(strName + " " + strType);
                z++;
            }
            stbSqlGetHeaders.Append(" )");
            SqlCeCommand sceCreateTableCommand;
            string strCreateTableQuery = stbSqlGetHeaders.ToString();
            sceCreateTableCommand = new SqlCeCommand(strCreateTableQuery, sceConnection);

            sceCreateTableCommand.ExecuteNonQuery();


            StringBuilder stbSqlQuery = new StringBuilder();
            StringBuilder stbFields = new StringBuilder();
            StringBuilder stbParameters = new StringBuilder();

            stbSqlQuery.Append("insert into " + strTableName + " (");

            foreach (DataColumn col in dttTable.Columns)
            {
                stbFields.Append(col.ColumnName);
                stbParameters.Append("@" + col.ColumnName.ToLower());
                if (col.ColumnName != dttTable.Columns[dttTable.Columns.Count - 1].ColumnName)
                {
                    stbFields.Append(", ");
                    stbParameters.Append(", ");
                }
            }
            stbSqlQuery.Append(stbFields.ToString() + ") ");
            stbSqlQuery.Append("values (");
            stbSqlQuery.Append(stbParameters.ToString() + ") ");

            string strTotalRows = dttTable.Rows.Count.ToString();

            foreach (DataRow row in dttTable.Rows)
            {
                SqlCeCommand sceInsertCommand = new SqlCeCommand(stbSqlQuery.ToString(), sceConnection);
                foreach (DataColumn col in dttTable.Columns)
                {
                    if (col.ColumnName.ToLower() == "ssma_timestamp")
                    {
                        sceInsertCommand.Parameters.AddWithValue("@" + col.ColumnName.ToLower(), "");
                    }
                    else
                    {
                        sceInsertCommand.Parameters.AddWithValue("@" + col.ColumnName.ToLower(), row[col.ColumnName]);
                    }
                }
                sceInsertCommand.ExecuteNonQuery();
            }
        }
        catch { }
    }
于 2012-06-08T11:51:19.233 回答