Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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# DbContext不';t发布SQLite数据库_C#_Sqlite_Entity Framework 4_Filelock_File Move - Fatal编程技术网

C# DbContext不';t发布SQLite数据库

C# DbContext不';t发布SQLite数据库,c#,sqlite,entity-framework-4,filelock,file-move,C#,Sqlite,Entity Framework 4,Filelock,File Move,首先,我的意图如下: 在SQLite上创建DbContext 从它读写 密切上下文 将文件移动到其他位置 第1-3点非常有效。当我尝试移动数据库时,问题就开始了。我得到一个错误声明: 'The process cannot access the file because it is being used by another process.' 我如何解决这个问题 首先,我创建一个上下文。我必须在几种方法中使用它,我不想每次需要时都创建它。因此,我将其存储为一个成员 _sqliteConte

首先,我的意图如下:

  • 在SQLite上创建DbContext
  • 从它读写
  • 密切上下文
  • 将文件移动到其他位置
  • 第1-3点非常有效。当我尝试移动数据库时,问题就开始了。我得到一个错误声明:

    'The process cannot access the file because it is being used by another process.' 
    
    我如何解决这个问题

    首先,我创建一个上下文。我必须在几种方法中使用它,我不想每次需要时都创建它。因此,我将其存储为一个成员

    _sqliteContext = new SqlLiteContext(sqliteContextName);
    
    然后我想访问一个名为
    sync
    的表并获取其最新条目

    var sync = _sqliteContext.Syncs.OrderByDescending(s => s.Date);
    _lastSync = sync.Any() ? sync.First().Date : new DateTime(0);
    
    就这样。然后我关闭上下文

    _sqliteContext.Dispose();
    
    并尝试移动文件

    File.Move(sqliteUploadLocation, sqliteDownloadLocation);
    
    这就是我得到例外的地方

    当我将选择替换为插入时,如下所示:

    var sync = new Sync { Id = Guid.NewGuid().ToString(), Date = DateTime.Now };
    _sqliteContext.Syncs.Add(sync);
    _sqliteContext.SaveChanges();
    
    这是可行的,我可以移动数据库。知道为什么我的选择没有释放锁吗

    更新


    更新2



    我想到两件事:

  • 确保Visual Studio未锁定数据库文件。打开服务器资源管理器,如果有与该文件的连接,请确保其已关闭或已完全删除
  • 连接池很可能是保持连接打开的原因。在连接字符串中禁用池,如下所示:
  • 数据源=e:\mydb.db;版本=3池=假


    正如Matt指出的,您应该真正使用using语句,而不是手动调用dispose。这样,如果出现异常,资源总是被正确释放。

    我发现另一个主题也有同样的问题。在我重构代码之后,我添加了

    GC.Collect();
    
    这移除了文件锁,我可以移动文件

    File.Move(sqliteUploadLocation, sqliteDownloadLocation);
    

    请参阅:

    能否显示您的实际代码,以便所有内容都在同一块中(我的意思是,由于上下文生命周期的关系,更容易看到实际的执行流)?@ken2k完成。您还需要更多吗?什么是
    SqlLiteContext
    ?它是否封装了实体框架上下文?一个想法:是否有类似SQLite的连接池?在这种情况下,请关闭它。您应该更喜欢使用“using”而不是手动调用Dispose。如果抛出(初始值设定项和Dispose之间的任何调用),它将不会通过SqlLiteContext调用Dispose。尝试一下,看看该行为是否与直接调用Dispose有所不同——它调用内部保护方法Dispose(bool)的方式可能会有所不同。我重构了代码,但数据库锁仍然没有消失。我在顶部的问题中添加了我的新代码。将“pooling=false”添加到数据源没有帮助。。。我真的很沮丧…:(为了确保GC真正同步地完成其工作,还可以调用
    GC.WaitForPendingFinalizers()
    using (var sqliteContext = new SqlLiteContext(_sqliteContextName))
    {
        // Read last sync date.
        var sync = sqliteContext.Syncs.Select(s => s).OrderByDescending(s => s.Date);
        var lastSync = sync.Any() ? sync.First().Date : new DateTime(1900, 1, 1);
    
        using (var mssqlContext = new MsSqlContext(_mssqlConnString))
        {
            SyncTablePerson(sqliteContext, mssqlContext, lastSync);
            SyncTableAddressAllocation(sqliteContext, mssqlContext, lastSync);
    
            // Save server changes.
            mssqlContext.SaveChanges();
        }
    
        // Creates an entry for this synchronisation.
        sqliteContext.Syncs.Add(new Sync { Id = Guid.NewGuid().ToString(), Date = DateTime.Now });
    
        // Save local changes.
        sqliteContext.SaveChanges();
    }
    
    GC.Collect();