Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么此查询会生成文件共享冲突?_C#_Compact Framework_Sql Server Ce_Windows Ce - Fatal编程技术网

C# 为什么此查询会生成文件共享冲突?

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

下面的代码给出了错误(我从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\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,并带有前缀“”正在被抛到一根弦上。看起来是错误的和过时的,但试图使这些东西现代化在很大程度上是一种沮丧和徒劳的练习。我要在这里添加的评论太长了,所以如果你有兴趣在你的酒中有那种蜘蛛网的感觉,请看我的更新。我已经“重新开始”使用此方法,通过复制项目中的现有代码,我认为这将解决此特定问题(项目确实使用了对其管理的连接的引用),但已转到当前导致的异常: