DbContext不释放SQLite数据库 [英] DbContext doesn't release SQLite database

查看:179
本文介绍了DbContext不释放SQLite数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,这些是我的意图:

First, these are my intentions:


  1. 在SQLite上创建一个DbContext

  2. $ / $>
  3. 将文件移动到另一个位置

$ b $点数1-3工作完美。当我尝试移动数据库时,问题开始。我收到一个错误,指出:

Points 1-3 work perfectly. The problem starts when I try to move the database. I get an error stating that:

'The process cannot access the file because it is being used by another process.' 

我该如何解决?

我创建一个上下文。我必须使用它在几种方法,我不想创建它每次我需要它。所以我把它存储为一个成员。

First, I create a context. I have to use it in several methods, and I don't want to create it every time I need it. So I am storing it as a member.

_sqliteContext = new SqlLiteContext(sqliteContextName);

然后我想访问一个名为 sync 并获取其最新条目。

Then I want to access a table called sync and get its latest entry.

var sync = _sqliteContext.Syncs.OrderByDescending(s => s.Date);
_lastSync = sync.Any() ? sync.First().Date : new DateTime(0);

就是这样。然后我关闭上下文。

That's it. Then I close the context.

_sqliteContext.Dispose();

并尝试移动文件。

File.Move(sqliteUploadLocation, sqliteDownloadLocation);

这是我得到例外的地方。

This is where I get the exception.

当我用插入替换选项时,如下所示:

When I replace the selection with an insert, like the following:

var sync = new Sync { Id = Guid.NewGuid().ToString(), Date = DateTime.Now };
_sqliteContext.Syncs.Add(sync);
_sqliteContext.SaveChanges();

这个工作,我可以移动数据库。任何想法为什么我的选择不释放锁?

This works, and I can move the database. Any ideas why my selection doesn't release its lock?

更新

// Start synchronisation.
new SyncManager(mssqlString, sqliteUploadLocation).Start();

// Move file from upload to download location.
try
{
    File.Move(sqliteUploadLocation, sqliteDownloadLocation);
}
catch (Exception ex)
{
    Console.WriteLine("Moving failed!");
    Console.WriteLine(ex.Message);
}

public void Start()
{
    // Create connection string for the sqlite database.
    const string sqliteContextName = "SqLiteContext";
    var sqliteConnStringSettings = new ConnectionStringSettings
        {
            Name = sqliteContextName,
            ConnectionString = "Data Source=" + _sqliteUploadLocation + ";Version=3;BinaryGUID=False;",
            ProviderName = "System.Data.SQLite"
        };

    // Read configuration, delete available connection strings and add ours.
    var conf = ConfigurationManager.OpenMachineConfiguration();
    var connStrings = conf.ConnectionStrings;
    connStrings.ConnectionStrings.Remove(sqliteContextName);
    connStrings.ConnectionStrings.Add(sqliteConnStringSettings);
    try
    {
        conf.Save(ConfigurationSaveMode.Minimal);
    }
    catch (Exception)
    {
        // Insufficient rights to save.
        return;
    }

    ConfigurationManager.RefreshSection("connectionStrings");

    // Create connection to the sqlite database.
    _sqliteContext = new SqlLiteContext(sqliteContextName);

    // Create connection to the mssql database.
    _mssqlContext = new MsSqlContext(_mssqlConnString);

    // Read last sync date.
    var sync = _sqliteContext.Syncs.OrderByDescending(s => s.Date);
    _lastSync = sync.Any() ? sync.First().Date : new DateTime(0);

    // Synchronize tables.
    //SyncTablePerson();
    //SyncTableAddressAllocation();

    // Creates an entry for this synchronisation.
    CreateSyncEntry();

    // Release resources.
    _sqliteContext.Dispose();
    _mssqlContext.Dispose();
}

private void CreateSyncEntry()
{
    var sync = new Sync { Id = Guid.NewGuid().ToString(), Date = DateTime.Now };
    _sqliteContext.Syncs.Add(sync);
    _sqliteContext.SaveChanges();
}

更新2

public class SqlLiteContext : Context
{
    public DbSet<Sync> Syncs { get; set; }

    public SqlLiteContext(string connectionString)
        : base(connectionString)
    {
        Database.SetInitializer(new NoOperationStrategy<SqlLiteContext>());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new PersonConfig());
        modelBuilder.Configurations.Add(new AddressAllocationConfig());
        modelBuilder.Configurations.Add(new AddressConfig());
        modelBuilder.Configurations.Add(new SyncConfig());
    }
}

public class NoOperationStrategy<T> : IDatabaseInitializer<T> where T : DbContext
{
    public void InitializeDatabase(T context)
    {
    }
}

public abstract class Context : DbContext
{
    public DbSet<Person> Persons { get; set; }
    public DbSet<AddressAllocation> AddressAllocations { get; set; }
    public DbSet<Address> Addresses { get; set; }

    protected Context(string connectionString)
        : base(connectionString)
    {
    }
}

使用

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();
}


推荐答案

同样的问题。在我重构代码之后,我添加了

I found another topic with the same problem. After i refactored my code, i added

GC.Collect();

删除文件锁,我可以移动文件。

That removed the file lock and i could move the file.

请参阅: https://stackoverflow.com/a/14151917/2462736

这篇关于DbContext不释放SQLite数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆