我的应用程序是一个依赖于数据库的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。验证此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连接获得的DataSet,这个DataSet我正在尝试写入我的本地数据库。
这可能是因为这是一个来自SQL连接的DataSet,而且我不能通过我的OleDbAdapter将它写入我的mdb连接,或者我只是错过了这里显而易见的?
感谢任何帮助。
谢谢,
凯文
答案 0 :(得分: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一样的自动递增键?
答案 1 :(得分:0)
我认为第一步是减少对static
方法和字段的依赖。
如果您查看UpdateLocalDatabase
方法,就会看到您传入strTableName
该方法使用的方法,但UpdateLocalDatabase
调用的方法CreateDatabaseConnection
)指的是一个名为相同的不同全局静态变量。很可能两个strTableName
变量包含不同的值,并且您没有看到它们不是同一个变量。
此外,您正试图在dtsTableContents
中写出全局静态数据集UpdateLocalDatabase
,但如果您再查看CreateDatabaseConnection
,它实际上会创建该变量的本地版本 - 再次,你有两个变量命名相同的东西,其中一个是全局的,一个是本地的。
我怀疑dtsTableContents
的两个变量是问题所在。
我的建议再一次是,没有任何静态方法或变量,对于你在这里做的事情,尽量不要使用任何全局变量。此外,重构和/或重命名您的方法以匹配他们实际正在做的事情。
答案 2 :(得分:0)
在无休止地尝试使用DataAdapter.Update(方法)后,我放弃了..我决定使用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 { }
}