【发布时间】:2013-03-25 13:22:25
【问题描述】:
下面的代码给了我错误(我从 catch 块中的 MessageBox.Show() 得到它)
"PopulateBla() 中的异常:存在文件共享冲突。A 不同的进程可能正在使用文件 [,,,,,,]
代码
using (SqlCeCommand cmd = new SqlCeCommand(SQL_GET_VENDOR_ITEMS, new SqlCeConnection(SQLCE_CONN_STR)))
{
cmd.Parameters.Add("@VendorID", SqlDbType.NVarChar, 10).Value = vendorId;
cmd.Parameters.Add("@VendorItemID", SqlDbType.NVarChar, 19).Value = vendorItemId;
try
{
cmd.Connection.Open();
using (SqlCeDataReader SQLCEReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (SQLCEReader.Read())
{
itemID = SQLCEReader.GetString(ITEMID_INDEX);
packSize = SQLCEReader.GetString(PACKSIZE_INDEX);
recordFound = true;
}
}
}
catch (SqlCeException err)
{
MessageBox.Show(string.Format("Exception in PopulateControlsIfVendorItemsFound: {0}\r\n", err.Message));//TODO: Remove
}
finally
{
if (cmd.Connection.State == ConnectionState.Open)
{
cmd.Connection.Close();
}
}
}
SQL_GET_VENDOR_ITEMS 是我的查询字符串。
这里可能会发生什么文件共享问题?
更新
这种代码使得 ctacke 推荐的重构变得困难:
public void setINVQueryItemGroup( string ID )
{
try
{
dynSQL += " INNER JOIN td_item_group ON t_inv.id = td_item_group.id AND t_inv.pack_size = td_item_group.pack_size WHERE td_item_group.item_group_id = '" + ID + "'";
}
catch( Exception ex )
{
CCR.ExceptionHandler( ex, "InvFile.setINVQueryDept" );
}
}
通过单独的方法附加 SQL 语句,更改全局变量 (dynSQL),同时可能允许 SQL 注入(取决于分配 ID 的位置/方式)。如果这还不够,任何抛出的异常都可能误导疲倦的 bughunter,因为它表明它发生在不同的方法中(无疑是粗心的复制和粘贴操作的受害者)。
这是“编码恐怖” - 值得。几行代码可以忽略多少最佳实践?
这是另一个例子:
string dynSQL = "SELECT * FROM purgatory WHERE vendor_item = '" + VendorItem + "' ";
if (vendor_id != "")
{
dynSQL += "AND vendor_id = '" + vendor_id + "' ";
}
可以通过将 args 替换为“?”来完成,但是用于确定要分配哪些/多少参数的代码将比 Joe Garagiola 的平均夹板丑 42 倍。
【问题讨论】:
-
您是否有机会通过网络文件夹访问您的数据库文件?
-
不,这是安装在手持设备上的 Windows CE 应用程序中的嵌入式 SQL Server CE 数据库。
-
那么可能有东西锁定了它的文件。
new SqlCeConnection(SQLCE_CONN_STR)失败了。 -
那个 finally 块是多余的,不是吗,用 using 语句呢?
-
问题可能出在其他仍然有连接打开的地方。将
using语句放在您的连接对象上。
标签: c# compact-framework sql-server-ce windows-ce