我应该重构这个吗,还是我的困惑引起了谨慎?
本文关键字:我的 重构 我应该 | 更新日期: 2023-09-27 18:06:46
这段SqlCe代码看起来非常奇怪:
cmd.CommandText = "INSERT INTO departments ( account_id, name) VALUES (?, ?)";
foreach(DataTable tab in dset.Tables)
{
if (tab.TableName == "Departments")
{
foreach(DataRow row in tab.Rows)
{
Department Dept = new Department();
if (!ret)
ret = true;
foreach(DataColumn column in tab.Columns)
{
if (column.ColumnName == "AccountID")
{
Dept.AccountID = (string) row[column];
}
else if (column.ColumnName == "Name")
{
if (!row.IsNull(column))
Dept.AccountName = (string) row[column];
else
Dept.AccountName = "";
}
}
List.List.Add(Dept);
. . .
dSQL = "INSERT INTO departments ( account_id, name) VALUES ('" + Dept.AccountID + "','" + Dept.AccountName +"')";
if (!First)
{
cmd.Parameters[0].Value = Dept.AccountID;
cmd.Parameters[1].Value = Dept.AccountName;
}
if (First)
{
cmd.Parameters.Add("@account_id",Dept.AccountID);
cmd.Parameters.Add("name",Dept.AccountName);
cmd.Prepare();
First = false;
}
if (frmCentral.CancelFetchInvDataInProgress)
{
ret = false;
return ret;
}
try
{
dbconn.DBCommand( cmd, dSQL, true );
}
. . .
public void DBCommand(SqlCeCommand cmd, string dynSQL, bool Silent)
{
SqlCeTransaction trans = GetConnection().BeginTransaction();
cmd.Transaction = trans;
try
{
cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception ex)
{
try
{
trans.Rollback();
}
catch (SqlCeException)
{
// Handle possible exception here
}
MessageBox.Show("DBCommand Except 2"); // This one I haven't seen...
WriteDBCommandException(dynSQL, ex, Silent);
}
}
我的问题是:
1)在赋值给cmd时真的应该使用"?"吗?CommandText,还是应该用"@"代替?
2)"cmd.Parameters.Add()"' s (account_id)使用"@",而另一个(name)没有。哪种方式是正确的,或者"@"是可选的?
3)我无法理解为什么DBCommand()是这样写的-最后两个参数只在有异常的情况下使用…??
我想从根本上重构这段代码,因为它看起来很奇怪,但由于我真的不理解它,这可能是一个灾难的食谱…
我敢肯定这篇文章会回答你的一些问题:
http://msdn.microsoft.com/en-us/library/yy6y35y8.aspx第二个图表解释了命名参数和位置参数(?)之间的区别(在OleDb和ODBC中使用)。
我相信在这种情况下?时,@是可选的,但我不确定。如果它在工作,我想说就是这样。
DBCommand中的内容似乎只是用于记录目的。如果执行失败,它将尝试执行回滚,然后使用sql命令(在dynSQL
中)记录异常。
?
参数是旧的Access语法。
我猜这曾经是一个Access数据库,但有人在某个时候将其转换为SQL CE。
一般来说,SQL理解?
参数,但最好只是改变,而你在那里,使它更容易理解。
我还在努力让头像&所有这些变量的尾部。如果我把它整理好,我将发布可编译的代码。
EDIT:我必须把它放入一个方法中,并找出所有RED错误,以确保我没有给你一些无法编译的东西。
我像这样传递了你的数据集,添加了很多注释:
private bool StrangeSqlCeCode(DataSet dset) {
const string ACCOUNT_ID = "AccountID";
const string DEPARTMENTS = "Departments";
const string NAME = "Name";
const string SQL_TEXT = "INSERT INTO departments (account_id, name) VALUES (@account_id, @name)";
bool ret = false;
//bool First = false; (we don't need this anymore, because we initialize the SqlCeCommand correctly up front)
using (SqlCeCommand cmd = new SqlCeCommand(SQL_TEXT)) {
// Be sure to set this to the data type of the database and size field
cmd.Parameters.Add("@account_id", SqlDbType.NVarChar, 100);
cmd.Parameters.Add("@name", SqlDbType.NVarChar, 100);
if (-1 < dset.Tables.IndexOf(DEPARTMENTS)) {
DataTable tab = dset.Tables[DEPARTMENTS];
foreach (DataRow row in tab.Rows) {
// Check this much earlier. No need in doing all the rest if a Cancel has been requested
if (!frmCentral.CancelFetchInvDataInProgress) {
Department Dept = new Department();
if (!ret)
ret = true;
// Wow! Long way about getting the data below:
//foreach (DataColumn column in tab.Columns) {
// if (column.ColumnName == "AccountID") {
// Dept.AccountID = (string)row[column];
// } else if (column.ColumnName == "Name") {
// Dept.AccountName = !row.IsNull(column) ? row[column].ToString() : String.Empty;
// }
//}
if (-1 < tab.Columns.IndexOf(ACCOUNT_ID)) {
Dept.AccountID = row[ACCOUNT_ID].ToString();
}
if (-1 < tab.Columns.IndexOf(NAME)) {
Dept.AccountName = row[NAME].ToString();
}
List.List.Add(Dept);
// This statement below is logically the same as cmd.CommandText, so just don't use it
//string dSQL = "INSERT INTO departments ( account_id, name) VALUES ('" + Dept.AccountID + "','" + Dept.AccountName + "')";
cmd.Parameters["@account_id"].Value = Dept.AccountID;
cmd.Parameters["@name"].Value = Dept.AccountName;
cmd.Prepare(); // I really don't ever use this. Is it necessary? Perhaps.
// This whole routine below is already in a Try/Catch, so this one isn't necessary
//try {
dbconn.DBCommand(cmd, true);
//} catch {
//}
} else {
ret = false;
return ret;
}
}
}
}
return ret;
}
我为你的DBCommand方法写了一个重载来处理遗留代码:
public void DBCommand(SqlCeCommand cmd, string dynSQL, bool Silent) {
cmd.CommandText = dynSQL;
DBCommand(cmd, Silent);
}
public void DBCommand(SqlCeCommand cmd, bool Silent) {
string dynSQL = cmd.CommandText;
SqlCeTransaction trans = GetConnection().BeginTransaction();
cmd.Transaction = trans;
try {
cmd.ExecuteNonQuery();
trans.Commit();
} catch (Exception ex) {
try {
trans.Rollback(); // I was under the impression you never needed to call this.
// If Commit is never called, the transaction is automatically rolled back.
} catch (SqlCeException) {
// Handle possible exception here
}
MessageBox.Show("DBCommand Except 2"); // This one I haven't seen...
//WriteDBCommandException(dynSQL, ex, Silent);
}
}