使用Entity Framework Core创建受密码保护的SQLite数据库

时间:2017-02-28 15:42:56

标签: c# sqlite entity-framework-core

尝试创建一个受密码保护的sqlite db,如Password protected SQLite with Entity Framework Core

但是当使用EnsureCreated();创建数据库时,它会抛出一个处置异常的对象。

ObjectDisposedException screenshot

我不知道为什么应该有一个处理过的SQLiteCommand对象?

添加了nuget包

Microsoft.EntityFrameworkCore.Sqlite v1.1.0
System.Data.SQLite.Core v1.0.104

DbContext类

using Microsoft.EntityFrameworkCore;
using System.Data.SQLite;

class TestMenuDataContext : DbContext
{
    public SQLiteConnection Connection { get; set; } 
    public SQLiteCommand Command { get; set; }

    public TestMenuDataContext()
    {
        //Database.Migrate();
        //Database.EnsureCreated();
    }

    public DbSet<Test> TestMenu { get; set; }
    ... and some more other tables ...

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        Connection = new SQLiteConnection(@"Data Source=TestMenu.db;");
        Connection.Open();

        Command = Connection.CreateCommand();
        Command.CommandText = "SELECT quote($password);";
        Command.Parameters.AddWithValue("$password", "TheUltimatePasswordPhraseWillBeAddedLaterHere");
        var escapedPassword = (string)Command.ExecuteScalar();

        Command.Parameters.Clear();
        Command.CommandText = "PRAGMA key = " + escapedPassword + ";";
        Command.ExecuteNonQuery();

        optionsBuilder.UseSqlite(Connection);

        // instead of password configuration above with this single line (no pw) below everything is fine
        //optionsBuilder.UseSqlite("Filename=./TestMenu.db");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        ... some key constraints
    }
}

WPF Gui中的调用部分(无MVVM)

private TestMenuDataContext _Db;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    //Do not load your data at design time.
    if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
    {
        _Db = new TestMenuDataContext();
        _Db.Database.EnsureCreated();

在此之前,我有本地上下文对象和本地连接和命令对象。像:

using (var db = new TestMenuDataContext())
{
    db.Database.EnsureCreated();

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    var conn = new SQLiteConnection(@"Data Source=yourSQLite.db;");
    conn.Open();

    var command = conn.CreateCommand();
    command.CommandText = "PRAGMA key = password;";
    command.ExecuteNonQuery();

    optionsBuilder.UseSqlite(conn);

编辑28Feb2017:
另外经过测试,如C# SQLite, database being left locked after a read

中提出的那样
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    using (SQLiteConnection connection = new SQLiteConnection(@"Data Source=TestMenu.db;"))
    using (SQLiteCommand command = connection.CreateCommand())
    {
        connection.Open();

        command.CommandText = "SELECT quote($password);";
        command.Parameters.AddWithValue("$password", "TheUltimatePasswordPhraseWillBeAddedHere");
        var escapedPassword = (string)command.ExecuteScalar();

        command.Parameters.Clear();
        command.CommandText = "PRAGMA key = " + escapedPassword + ";";
        command.ExecuteNonQuery();

        optionsBuilder.UseSqlite(connection);
    }

0 个答案:

没有答案