C# 继承问题-从Access数据库文件和SQL Express检索数据
我正在开发一个应用程序,它将在一开始连接到Access数据库,计划在不久的将来切换到MS SQL或SQL Express。datatables结构对于这两种类型的数据库都是相同的,我试图避免重复代码,并试图找到最小化代码的方法 例如,我编写了以下函数,用于从Access数据库检索数据:C# 继承问题-从Access数据库文件和SQL Express检索数据,c#,database,ms-access,inheritance,sql-server-express,C#,Database,Ms Access,Inheritance,Sql Server Express,我正在开发一个应用程序,它将在一开始连接到Access数据库,计划在不久的将来切换到MS SQL或SQL Express。datatables结构对于这两种类型的数据库都是相同的,我试图避免重复代码,并试图找到最小化代码的方法 例如,我编写了以下函数,用于从Access数据库检索数据: public static DataTable GetActiveCalls() { string select = "SELECT call_id, call_time, msisdn,
public static DataTable GetActiveCalls()
{
string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
OleDbCommand cmd = new OleDbCommand(select, conn);
DataTable dt = new DataTable("Active Calls");
OleDbDataAdapter DA = new OleDbDataAdapter(cmd);
try
{
conn.Open();
DA.Fill(dt);
}
catch (Exception ex)
{
string sDummy = ex.ToString();
}
finally
{
conn.Close();
}
return dt;
}
public static DataTable GetActiveCalls()
{
string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
SqlCommand cmd = new SqlCommand(select, conn);
DataTable dt = new DataTable("Active Calls");
SqlDataAdapter DA = new SqlDataAdapter(cmd);
try
{
conn.Open();
DA.Fill(dt);
}
catch (Exception ex)
{
string sDummy = ex.ToString();
}
finally
{
conn.Close();
}
return dt;
}
以下代码适用于SQL Express数据库:
public static DataTable GetActiveCalls()
{
string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
OleDbCommand cmd = new OleDbCommand(select, conn);
DataTable dt = new DataTable("Active Calls");
OleDbDataAdapter DA = new OleDbDataAdapter(cmd);
try
{
conn.Open();
DA.Fill(dt);
}
catch (Exception ex)
{
string sDummy = ex.ToString();
}
finally
{
conn.Close();
}
return dt;
}
public static DataTable GetActiveCalls()
{
string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
SqlCommand cmd = new SqlCommand(select, conn);
DataTable dt = new DataTable("Active Calls");
SqlDataAdapter DA = new SqlDataAdapter(cmd);
try
{
conn.Open();
DA.Fill(dt);
}
catch (Exception ex)
{
string sDummy = ex.ToString();
}
finally
{
conn.Close();
}
return dt;
}
这两种方法几乎相同。唯一的区别是SqlCommand/OleDbCommand和SqlDataAdapter/OleDbDataAdapter。
还有一些方法以参数为例:
public static void AddMessage(string callID, string content)
{
string select =
"INSERT INTO message(key, direction, content, read, write_time) VALUES (@callId, 0, @content, 0, @insertTime)";
OleDbCommand cmd = new OleDbCommand(select, conn);
cmd.Parameters.AddWithValue("callId", callID.ToString());
cmd.Parameters.AddWithValue("content", content);
cmd.Parameters.AddWithValue("insertTime", DateTime.Now.ToString());
try
{
conn.Open();
cmd.ExecuteScalar();
}
catch (Exception ex)
{
string sDummy = ex.ToString();
}
finally
{
conn.Close();
}
}
string sql = @"UPDATE tblContent
SET Title = @Title, Content = @Content, IsPublic = @IsPublic, ItemOrder = @ItemOrder
WHERE ContentItemID = @ContentItemID";
Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
db.AddInParameter(cmd, "Title", DbType.String, title);
db.AddInParameter(cmd, "Content", DbType.String, content);
db.AddInParameter(cmd, "IsPublic", DbType.Boolean, isPublic);
db.AddInParameter(cmd, "ItemOrder", DbType.Int32, itemOrder);
db.AddInParameter(cmd, "ContentItemID", DbType.Int32 , contentItemID);
db.ExecuteNonQuery(cmd);
}
在本例中,两个数据库的SQL查询字符串也是相同的,但cmd(SqlCommand/OleDbCommand)的类型有所不同
如果有人能就如何避免重复代码和优化给定问题提出建议,我将不胜感激。您可以使用独立于数据库的接口IDbDataAdapter和IDbCommand,然后使用工厂创建具体实例。这就是一个例子
但是,我建议您使用ORM解决方案,例如如果您的应用程序不是很简单,因为Access和SQL Server之间的SQL语言没有什么区别,这会使您的数据访问代码更加复杂。您应该看看数据访问位。底层数据库提供程序的细节将为您抽象出来。例如:
public static void AddMessage(string callID, string content)
{
string select =
"INSERT INTO message(key, direction, content, read, write_time) VALUES (@callId, 0, @content, 0, @insertTime)";
OleDbCommand cmd = new OleDbCommand(select, conn);
cmd.Parameters.AddWithValue("callId", callID.ToString());
cmd.Parameters.AddWithValue("content", content);
cmd.Parameters.AddWithValue("insertTime", DateTime.Now.ToString());
try
{
conn.Open();
cmd.ExecuteScalar();
}
catch (Exception ex)
{
string sDummy = ex.ToString();
}
finally
{
conn.Close();
}
}
string sql = @"UPDATE tblContent
SET Title = @Title, Content = @Content, IsPublic = @IsPublic, ItemOrder = @ItemOrder
WHERE ContentItemID = @ContentItemID";
Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
db.AddInParameter(cmd, "Title", DbType.String, title);
db.AddInParameter(cmd, "Content", DbType.String, content);
db.AddInParameter(cmd, "IsPublic", DbType.Boolean, isPublic);
db.AddInParameter(cmd, "ItemOrder", DbType.Int32, itemOrder);
db.AddInParameter(cmd, "ContentItemID", DbType.Int32 , contentItemID);
db.ExecuteNonQuery(cmd);
}
……或者
string sql = "SELECT MenuText FROM tblMenuItems WHERE MenuItemID = @MenuItemID";
Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
db.AddInParameter(cmd, "MenuItemID", DbType.Int32, menuItemID);
using(IDataReader dr = db.ExecuteReader(cmd))
{
while(dr.Read())
{
return dr["MenuText"].ToString();
}
return null;
}
}
以上两个示例都适用于Access和MS SQL,如果您坚持使用与Jet和MS SQL兼容的SQL语句,您应该不会遇到任何问题
从Access切换到MS SQL时,只需更改连接字符串,例如,从:
<connectionStrings>
<add
name="ContentManager"
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Content.mdb;"
providerName="System.Data.OleDb"/>
</connectionStrings>
…到
<connectionStrings>
<add
name="ContentManager"
connectionString="Data Source=your.sql.server;Initial Catalog=content;Persist Security Info=True;User ID=cmuser;Password=password"
providerName="System.Data.SqlClient" />
</connectionStrings>
要实现这一点,您只需在EL发行版中引用以下DLL:
Microsoft.Practices.EnterpriseLibrary.Common.dllMicrosoft.Practices.EnterpriseLibrary.Data.dll 很值得一看 干杯
Kev+1表示SQL中的细微差异。我还建议使用ProviderFactory()