C# 为什么此查询会生成文件共享冲突?
下面的代码给出了错误(我从catch块中的C# 为什么此查询会生成文件共享冲突?,c#,compact-framework,sql-server-ce,windows-ce,C#,Compact Framework,Sql Server Ce,Windows Ce,下面的代码给出了错误(我从catch块中的MessageBox.Show()中获取) “PopulateBla()中出现异常:存在文件共享冲突。a 不同的进程可能正在使用文件[,,,,,,] 代码 using (SqlCeCommand cmd = new SqlCeCommand(SQL_GET_VENDOR_ITEMS, new SqlCeConnection(SQLCE_CONN_STR))) { cmd.Parameters.Add("@VendorID", SqlDbType
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\u GET\u VENDOR\u 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替换为“?”s来完成,但随后确定要分配哪个/多少个参数的代码将比Joe Garagiola的平均夹板更难看42倍。如果文件未标记为只读(您选中了,对吗?),那么您就有了另一个对文件具有非共享锁的进程 SQL CE附带的isql.exe数据库浏览器在后台运行时是常见的问题 根据您的SQLCE版本,另一个进程很可能有一个打开的连接(回忆不起哪个版本开始允许多个进程连接),因此,如果您在后台有任何其他应用程序打开了它,这可能也是一个问题
您还使用了大量到该数据库的连接,它们并不总是被清理并立即释放。我强烈建议构建一个简单的连接管理器类,该类保留一个(或更多类似于两个)连接连接到数据库,并在所有操作中重复使用它们。我非常喜欢Chris使用到数据库的单个连接的想法。您可以向类声明全局连接,如下所示:
public ClayShannonDatabaseClass
{
private SqlCeConnection m_openConnection;
public ClayShannonDatabaseClass()
{
m_openConnection = new SqlCeConnection();
m_openConnection.Open();
}
public void Dispose()
{
m_openConnection.Close();
m_openConnection.Dispose();
m_openConnection = null;
}
}
我猜每当你试图实际打开数据库时,你的代码都会崩溃
要验证这一点,可以在代码中插入一个整数值以帮助调试
例如:
int debugStep = 0;
try
{
//cmd.Connection.Open(); (don't call this if you use m_openConnection)
debugStep = 1;
using (SqlCeDataReader SQLCEReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
debugStep = 2;
if (SQLCEReader.Read())
{
debugStep = 3;
itemID = SQLCEReader.GetString(ITEMID_INDEX);
debugStep = 4;
packSize = SQLCEReader.GetString(PACKSIZE_INDEX);
debugStep = 5;
recordFound = true;
}
}
}
catch (SqlCeException err)
{
string msg = string.Format("Exception in PopulateControlsIfVendorItemsFound: {0}\r\n", err.Message);
string ttl = string.Format("Debug Step: {0}", debugStep);
MessageBox.Show(msg, ttl); //TODO: Remove
}
// finally (don't call this if you use m_openConnection)
// {
// if (cmd.Connection.State == ConnectionState.Open)
// {
// cmd.Connection.Close();
// }
// }
我猜您的错误在第1步。您是否有机会通过网络文件夹访问您的数据库文件?没有,这是安装在手持设备上的Windows CE应用程序中的嵌入式SQL Server CE数据库。然后可能有什么东西锁定了其文件。这是新的SqlCeConnection(SQLCE\U CONN\U STR)失败。最后一个块是多余的,不是吗?using语句有什么问题?问题可能是在其他地方仍然有一个连接打开。将
using
语句放在您的连接对象上。*.sdf文件不是只读的。我不知道我的SQLCE版本,但.NET版本是1.1。我恐怕无法确定对这段代码进行任何彻底/重大的更改,因为它太复杂了,我不理解它的原因和原因,很可能会造成更大的混乱。我只想做最起码的必要工作,然后离开,继续其他项目。我理解你的挫折感,但如果它现在不起作用,进行更改似乎是一个理由le path forward。毫无疑问,您可以放弃大量的代码改进机会,但让它正常工作可能是必须的。就我个人而言,我已经构建了一台非虚拟机开发机器,以便在到达您现在的位置之前很久就可以进行有效调试。我要再次指出,.NET的版本不是1.1,而是1.0。没有CF1.1.事实证明,我所做的许多“改进”都必须返回并反转(例如在查询中用“@”替换“?”)和“.Add”(“+bla,Blah)”替换为“.Add(bla,Blah)”(其中“bla”是一个int,并带有前缀“”正在被抛到一根弦上。看起来是错误的和过时的,但试图使这些东西现代化在很大程度上是一种沮丧和徒劳的练习。我要在这里添加的评论太长了,所以如果你有兴趣在你的酒中有那种蜘蛛网的感觉,请看我的更新。我已经“重新开始”使用此方法,通过复制项目中的现有代码,我认为这将解决此特定问题(项目确实使用了对其管理的连接的引用),但已转到当前导致的异常: