使用bundle_e_sqlcipher和SqlSugarNoDrive的bug 返回

没有找到SqlSugarNoDrive的源码,感觉是在SplitTable的时候创建SqliteConnection的时候没有使用configAction
引用的库是:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.1" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.1.10" /> <PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.175" /> </ItemGroup> </Project>
代码是:
using SqlSugar; var connStr = @"Data Source=z.db;"; var _writeDB = new SqlSugarClient(new ConnectionConfig() { ConnectionString = connStr, DbType = DbType.Sqlite, }, db => { db.Ado.ExecuteCommand($"pragma key='abcde';"); db.Ado.ExecuteCommand($"PRAGMA cipher_compatibility = 3;"); } ); _writeDB.CodeFirst.InitTables<SplitRecord>(); var id = new Random().Next(); _writeDB.Insertable(new SplitRecord() { ID = id }).SplitTable().ExecuteCommand();//这句话报错了 var ret = _writeDB.Queryable<SplitRecord>().SplitTable().ToList(); Console.WriteLine(ret.Count); Console.Read(); [SplitTable(SplitType.Month)] [SugarTable("AlarmRecord_{year}{month}{day}")] public class SplitRecord { public int ID { set; get; } [SplitField] public DateTime Time { get; } = DateTime.Now; }
报错:
Microsoft.Data.Sqlite.SqliteException:“SQLite Error 26: 'file is not a database'.”
热忱回答(17)
-
鼠赽 VIP0
2周前感觉应该是SqlSugarProvider.CopyNew的问题,这里没有使用configAction
public SqlSugarClient CopyNew() { var result = new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig)); result.QueryFilter = this.QueryFilter; return result; }
0 回复 -
fate sta VIP0
2周前https://www.donet5.com/Home/Doc?typeId=2366
你上面代码并没用到CopyNew(), 按模版提供完整的demo
0 回复 -
鼠赽 VIP0
2周前using SqlSugar; namespace Test { internal class Program { static void Main(string[] args) { //创建连接 var connStr = @"Data Source=z.db;"; var _writeDB = new SqlSugarClient(new ConnectionConfig() { ConnectionString = connStr, DbType = DbType.Sqlite, IsAutoCloseConnection = false }, db => { //在这里初始化1是不想把密码暴露在ConnectionString里,2是希望能用cipher_compatibility=3 db.Ado.ExecuteCommand("pragma key='abcde';"); db.Ado.ExecuteCommand("PRAGMA cipher_compatibility = 3;"); } ); var id = new Random().Next(); //建表 _writeDB.CodeFirst.InitTables<SplitRecord>(); //插入数据,这一句出错 _writeDB.Insertable(new SplitRecord() { ID = id }).SplitTable().ExecuteCommand(); var ret = _writeDB.Queryable<SplitRecord>().SplitTable().ToList(); Console.WriteLine(ret.Count); Console.Read(); } //测试类,主要是SplitTable会引起问题 [SplitTable(SplitType.Month)] [SugarTable("AlarmRecord_{year}{month}{day}")] public class SplitRecord { public int ID { set; get; } [SplitField] public DateTime Time { get; } = DateTime.Now; } } }
实在不会改成黑底白字了。。。
以下都是我的猜测:
我开了SqlSugar的源码,也会出现这个问题。读源码可得:
在
_writeDB.Insertable(new SplitRecord() { ID = id }).SplitTable().ExecuteCommand();
中,会调用
SplitInsertable<T>.ExecuteCommand()
=>SplitInsertable<T>.CreateTable()
=>var newDb = this.Context.CopyNew();
跟踪线程的时候发现这里的 Context是SqlSugar.SqlSugarProvider
它的CopyNew是
public SqlSugarClient CopyNew() { var result = new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig)); result.QueryFilter = this.QueryFilter; return result; }
这里直接通过ConnectionString创建,就不会经过SqlSugarClient的configAction
导致不会执行
db.Ado.ExecuteCommand("pragma key='abcde';"); db.Ado.ExecuteCommand("PRAGMA cipher_compatibility = 3;");
这个新建的connection没有密码,所以在读写数据库的时候就会报错
Microsoft.Data.Sqlite.SqliteException:“SQLite Error 26:
'file is not a database'
.”
0 回复 -
fate sta VIP0
2周前你提供代码是可以跑的 ,我这边测试通过了,还有问题将能重现的DEMO删掉OBJ和BIN打包上传
0 回复 -
鼠赽 VIP0
2周前0 回复 -
fate sta VIP0
1周前应该是执行这个东西导致当前链接找不到库
db.Ado.ExecuteCommand("pragma key='abcde';");
db.Ado.ExecuteCommand("PRAGMA cipher_compatibility = 3;");
只要执行这2话就不行
0 回复 -
鼠赽 VIP0
1周前@fate sta:
这两行是sqlcipher用来设置密码和加密版本的,应该在连接的第一时间使用
我尝试在SqlSugar.SqlSugarProvider.CopyNew()中手动添加这两行,就不会有这个错误了
如果加密的数据库不用这两行直接读取,就会出现‘file is not a database'
0 回复 -
鼠赽 VIP0
1周前@fate sta:
总之就是SqlSugarClient的configAction,没有应用到某些copyNew里
主要出错的场景就是:
密码不是直接显示在ConnectionString而是对链接进行一些处理,此时用一些使用到copynew比如splittable中的一些操作,就会出错
0 回复 -
fate sta VIP0
1周前SqlSugar.SqlSugarProvider.CopyNew() 等于没有生效,是不同的db连接
0 回复 -
fate sta VIP0
1周前这样吧,你用ado.net写一个CRUD 示例能用的,我这边用sqlsugar按你要求进行测试
0 回复 -
鼠赽 VIP0
1周前static void Main(string[] args) { var connStr = @"Data Source=z.db;"; //创建数据库,用SqlCipher加密方式,所以这个数据库用sqlite studio之类的是打不开的 var fi = new FileInfo("z.db"); if (fi.Exists) { // fi.Delete(); } using (var conn = CreateByConnStr(connStr)) { CreateTable(conn); conn.Close(); } SqliteConnection.ClearAllPools(); //测试使用connectionstring方式加密,没问题 using (var conn = CreateByConnStr(connStr)) { Console.WriteLine("test by connectionstring"); TestConn(conn); conn.Close(); } SqliteConnection.ClearAllPools(); //测试使用命令的加密,没问题 using (var conn = CreateByAdo(connStr)) { Console.WriteLine("test by ado"); TestConn(conn); conn.Close(); } SqliteConnection.ClearAllPools(); //测试不加密连接,显示file is not a database using (var conn = CreateSurceConn(connStr)) { Console.WriteLine("test by source"); TestConn(conn); conn.Close(); } Console.WriteLine("end"); }
0 回复 -
鼠赽 VIP0
1周前@鼠赽:
着实是不太会用网页编辑,而且手头就一mac也不方便~源项目附上了
主要还是用sqlcipher加密数据库的话是有两种方式的(另外就是加密格式cipher_compatibility = 3好像只能用pragma设置)
1、密码填在ConnectionString里
2、在刚创建连接的时候pragma key=‘abcde’;
用第一种方式的话,这个密码是明文可见的,所以我比较希望能用第二种
如果用没有密码的connectionstring创建SqliteConnection的话,执行pramga key=‘abcde';就可以正常使用加密后的db文件
如果不执行的话,命令就会显示 file is not a database
大概应该就是这个情况
0 回复 -
fate sta VIP0
1周前db.ado.Connection=CreateByConnStr(connStr)这样就行,自动释放关闭用手动释放
0 回复 -
fate sta VIP0
1周前sqlsugar可以直接用ado.net的connection
0 回复 -
fate sta VIP0
1周前你拿上面的DEMO小改一下就能用了
0 回复 -
鼠赽 VIP0
5天前@fate sta:
主要是不想用ConnStr的方式,这种方式的SqlSugarClient可以直接从ConnStr中看到密码值。
想用 pramga key=‘abcde' 的方式实现。。。
而如果用pragma key="abcde"的方式手动创建SqliteConnection的话,在SplitTable中还是会用到SqlSugar.SqlSugarProvider.CopyNew(),通过ConnStr创建新连接
依然会出现这个错误
0 回复 -
鼠赽 VIP0
5天前@fate sta:
归纳一下:
我的主要目的是通过Execute("pragma key='abcde'")的方式实现加密
这样密码就不会体现在ConnectionString中(另外还有个小需求就是需要"PRAGMA cipher_compatibility = 3;")
而在SplitTable的一系列操作中,会通过ConnectionString生成一个新的连接用来处理CreateTable等操作(SqlSugar.SqlSugarProvider.CopyNew())
而这个新的db由于没有执行 pragma key='abcde' 会导致 file is not a database 错误
0 回复