EF Core 访问加密Sqlite异常解决方法

最近打算升级到EF Core ,数据库是Sqlite,找了一个案例,按步就班:

    public class SampleDBContext : DbContext

    {
        private SqliteConnection m_conn = null;
        public SqliteConnection Conn
        {
            get
            {
                if (m_conn == null)
                {
                    SQLitePCL.Batteries.Init();
                    string dbName=Path.Combine(Environment.CurrentDirectory, "SampleDB.db");
                    string connStr=new SqliteConnectionStringBuilder(){
                        DataSource= dbName,
                        Mode=SqliteOpenMode.ReadWriteCreate
                        ,Password ="admin"
                    }.ToString();
                    m_conn = new SqliteConnection(connStr);
                    m_conn.Open();
                }
                return m_conn;
            }
        }
        private static bool _created = false;
        public SampleDBContext()
        {
            if (!_created)
            {
                _created = true;
                Database.EnsureDeleted();
                Database.EnsureCreated();
            }
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
        {
            optionbuilder.UseSqlite(Conn);
        }
    }

运行后出现如下错误:

图1
Method not found: 'Int32 SQLitePCL.ISQLite3Provider.sqlite3_win32_set_directory(Int32, System.String)"

Method not found: 'Int32 SQLitePCL.ISQLite3Provider.sqlite3_win32_set_directory(Int32, System.String)"

注释掉SQLitePCL.Batteries.Init();问题依旧

图2

着重参考了下列两篇文章

https://www.bricelam.net/2016/06/13/sqlite-encryption.html

https://github.com/ericsink/SQLitePCL.raw/issues/290

折腾了好久,结果问题依旧,放弃吧......

不甘心,过了两天,重拾旧业,仔仔细细,反复查看,发现SQLitePCLRaw.bundle_sqlcipher(1.1.14)默认引用的SQLitePCLRaw.core是2.02版本

图3

而最新的SQLitePCLRaw.core是2.03版本,因此试着对包SQLitePCLRaw.provider.sqlcipher(2.03)及SQLitePCLRaw.core(2.03)进行显式引用,,结果...

图4

是新问题,然后,注释掉Database.EnsureDeleted(),再次编译,运行,终于...

图5

大功告成!

最后把对SQLitePCLRaw.core的显示引用去除,项目文件内容如下:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="3.1.4" />
    <PackageReference Include="SQLitePCLRaw.bundle_sqlcipher" Version="1.1.14" />
    <PackageReference Include="SQLitePCLRaw.provider.sqlcipher" Version="2.0.3" />
  </ItemGroup>
</Project>

解决新问题:

最后一个问题的出现,分析了一下原因,提示写着,数据库被其他进程占用了,通过跟踪发现其实并不是被其他进程占用了,而是调用Database.EnsureDeleted()时,连接已经打开了,optionbuilder.UseSqlite使用了SqliteConnection,把optionbuilder.UseSqlite的参数改为连接字符串,问题就消失了。

最终程序如下:

using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System;
using System.IO;
using System.Linq;

namespace EFCoreTest
{
    public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class SampleDBContext : DbContext
    {
        private SqliteConnection m_conn = null;
        public SqliteConnection Conn
        {
            get
            {
                if (m_conn == null)
                {
                    //SQLitePCL.Batteries.Init();
                    //string dbName=Path.Combine(Environment.CurrentDirectory, "SampleDB.db");
                    //string connStr=new SqliteConnectionStringBuilder(){
                    //    DataSource= dbName,
                    //    Mode=SqliteOpenMode.ReadWriteCreate
                    //    ,Password ="admin"
                    //}.ToString();
                    m_conn = new SqliteConnection(ConnStr);
                    m_conn.Open();
                }
                return m_conn;
            }
        }
        private string ConnStr
        {
            get
            {
                string dbName = Path.Combine(Environment.CurrentDirectory, "SampleDB.db");
                return new SqliteConnectionStringBuilder()
                {
                    DataSource = dbName,
                    Mode = SqliteOpenMode.ReadWriteCreate,
                    Password = "admin"
                }.ToString();
            }
        }
        private static bool _created = false;
        public SampleDBContext()
        {
            if (!_created)
            {
                _created = true;
                Database.EnsureDeleted();
                Database.EnsureCreated();
            }
        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Category>().ToTable("tb_Category");
        }
        protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
        {
            optionbuilder.UseSqlite(ConnStr);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //Console.WriteLine("Hello World!");

            using (var dbContext = new SampleDBContext())
            {
                dbContext.Set<Category>().Add(new Category { Name = "Wigs" });
                dbContext.Set<Category>().Add(new Category { Name = "Shoes" });
                dbContext.Set<Category>().Add(new Category { Name = "Dresses" });
                dbContext.SaveChanges();

                foreach (var cat in dbContext.Set<Category>().ToList())
                {
                    Console.WriteLine($"CategoryId= {cat.Id}, CategoryName = {cat.Name}");
                }
            }
            Console.ReadKey();
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你的 Python 程序无法读取已加密SQLite 数据库,可能有以下几个原因: 1. 没有安装 SQLite 加密扩展。SQLite 加密需要使用 SQLite 加密扩展,你需要先使用 pip 安装 pysqlcipher3 或者 pysqlite3 这两个扩展库。 2. 密码错误。如果你在打开加密SQLite 数据库时输入了错误的密码,Python 将无法读取数据库中的数据。请确保密码正确。 3. Python 版本不兼容。SQLite 加密扩展可能只支持特定版本的 Python,因此请务必检查你的 Python 版本是否与所使用的扩展库兼容。 4. 使用了错误的加密算法。SQLite 支持多种加密算法,如 AES-128、AES-192、AES-256 等。如果你使用了错误的加密算法,Python 也无法读取数据库中的数据。 解决方法: 1. 确认已经安装了 SQLite 加密扩展。你可以使用以下命令来安装 pysqlcipher3 或者 pysqlite3: pip install pysqlcipher3 或者 pip install pysqlite3 2. 确认密码是否正确。在 Python 中打开加密SQLite 数据库时,需要提供正确的密码。你可以尝试使用 SQLite 命令行工具打开数据库并输入密码,以确保密码正确。 3. 确认 Python 版本是否兼容。请查看 SQLite 加密扩展的文档,确认它支持的 Python 版本是否与你所使用的 Python 版本兼容。 4. 确认使用的加密算法是否正确。你可以尝试使用不同的加密算法打开数据库,以找到正确的算法。你也可以查阅 SQLite 加密扩展的文档,以确定正确的加密算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值