FreeSql.Provider.SqliteCore

nicye2022年3月25日大约 3 分钟约 1002 字

FreeSql.Provider.SqliteCore

FreeSql.Provider.SqliteCore是FreeSql基于微软提供的最新的Microsoft.Data.Sqlite.Coreopen in new window驱动的实现。 需要另外安装对应的bundle_xxx实现加密。

支持的版本

  • .NET Standard 2.0(支持.NETopen in new window Framework4.6.1+/支持.NET Core 2.0+)
  • net6.0
  • SQLite(3.7 及以上版本)
  • Linux ARM/X86/MAUI Android/MAUI iOS等

安装FreeSql.Provider.SqliteCore包。

dotnet add package FreeSql.Provider.SqliteCore
dotnet add package SQLitePCLRaw.bundle_e_sqlite3

SQLitePCLRaw.bundle_e_sqlite3 不支持加密,但此方式是官方实现的SQlite版本,以下二选一:

捆绑描述
SQLitePCLRaw.bundle_e_sqlite3在所有平台上提供一致版本的 SQLite。 包括 FTS4、FTS5、JSON1 和 R* 树扩展。 建议使用
SQLitePCLRaw.bundle_e_sqlcipher提供 SQLCipher 的非官方开放源代码内部版本,支持加密

只有 SQLitePCLRaw.bundle_e_sqlcipher 才支持加密

0.选择一个目录,创建一个控制台项目OvOv.FreeSqlMicrosoftSqliteCore

dotnet new console -n OvOv.FreeSqlMicrosoftSqliteCore
cd OvOv.FreeSqlMicrosoftSqliteCore

1.安装包

dotnet add package FreeSql.Provider.SqliteCore
dotnet add package SQLitePCLRaw.bundle_e_sqlcipher
  1. 连接串直接指定Password=xxx即可

创建一个类DB.cs,可直接通过DB.sqlite访问到IFreeSql对象

public class DB
{
    static Lazy<IFreeSql> sqliteLazy = new Lazy<IFreeSql>(() =>
    {
        var fsql = new FreeSql.FreeSqlBuilder()
                .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=local.db;Password=123qwe")
                .UseAutoSyncStructure(true)
                .UseLazyLoading(true)
                .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText))
                .Build();
        return fsql;
    }
   );
    public static IFreeSql sqlite => sqliteLazy.Value;
}

测试加密,增加一些数据。Program.cs中测试

Test();

static void Test()
{
    IInsert<Topic> insert = DB.sqlite.Insert<Topic>();
    var items = new List<Topic>();
    for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 });

    var affrows = insert.AppendData(items).ExecuteAffrows();
    Console.WriteLine("affrows:" + affrows);
    var list = DB.sqlite.Select<Topic>().ToList();
    Console.WriteLine("count:" + list.Count);
}

[Table(Name = "tb_topic_insert")]
class Topic
{
    [Column(IsIdentity = true, IsPrimary = true)]
    public int Id { get; set; }
    public int Clicks { get; set; }
    public string Title { get; set; }
    public DateTime CreateTime { get; set; }
}

运行项目

dotnet run

验证是否登录是否加密?

重新运行时,删除 连接串中的Password,发现无法获取数据。或使用Navicat Premium工具发现无法连接。

+ .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=local.db;") 
- .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|local.db;Password=123qwe")

提示如下内容,但使用密码时又能正常访问数据。

SqliteException: SQLite Error 26: 'file is not a database'.

相比包 FreeSql.Provider.Sqlite来说,目前存在一些限制,

|DataDirectory| 默认不支持

需要使用前,指定具体的文件夹,此处相当于指定了当前dll所在目录,即bin/Debug/net6.0。参考

string dataSubDirectory = Path.Combine(AppContext.BaseDirectory);

if (!Directory.Exists(dataSubDirectory))
    Directory.CreateDirectory(dataSubDirectory);

AppDomain.CurrentDomain.SetData("DataDirectory", dataSubDirectory);

public class DB
{
    static Lazy<IFreeSql> sqliteLazy = new Lazy<IFreeSql>(() =>
    {
        string dataSubDirectory = Path.Combine(AppContext.BaseDirectory);

        if (!Directory.Exists(dataSubDirectory))
            Directory.CreateDirectory(dataSubDirectory);

        AppDomain.CurrentDomain.SetData("DataDirectory", dataSubDirectory);

        var fsql = new FreeSql.FreeSqlBuilder()
                .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|local.db;Password=123qwe")
                .UseAutoSyncStructure(true)
                .UseLazyLoading(true)
                .UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText))
                .Build();

        return fsql;
    }
   );
    public static IFreeSql sqlite => sqliteLazy.Value;
}

具体的链接串,请参考 https://docs.microsoft.com/zh-cn/dotnet/standard/data/sqlite/connection-stringsopen in new window

数学函数

如下函数不支持

  • Floor
  • Ceiling
  • Log10
  • Pow
  • Sqrt
  • Cos

TimeSpanTest

测试 类中 不通过、ulong最大值,最小值,超出范围。

  • 不支持
  public void Days()
  {
      var data = new List<object>();
      data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList());
  }
  • 不支持
 public void Minutes()
  {
      var data = new List<object>();
      data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList());
  }

完整代码

iOS

https://docs.microsoft.com/zh-cn/dotnet/standard/data/sqlite/xamarin#iosopen in new window

Microsoft.Data.Sqlite 尝试自动初始化 SQLitePCLRaw 捆绑。 遗憾的是,由于针对 Xamarin.iOS 的预先 (AOT) 编译存在限制,因此尝试失败,并出现以下错误。

需要调用 SQLitePCL.raw.SetProvider()。 如果使用的是捆绑包,可以通过调用 SQLitePCL.Batteries.Init() 来完成此操作。

若要初始化该绑定,请在使用 Microsoft.Data.Sqlite 之前,将以下代码行添加到应用。

SQLitePCL.Batteries_V2.Init();

即在上方定义FreeSql单例时,在new Lazy内,调用一次即可。

.NET Framework 支持

有二种方法支持.NETopen in new window Framework(选择其中一个即可)

1.复制.NETopen in new window Core中的dll

创建一个.NETopen in new window Core的console项目,然后安装nuget包 SQLitePCLRaw.bundle_e_sqlcipher,编译后生成的bin\Debug\net5.0\runtimes\win-x64\native\e_sqlcipher.dll 复制到 .net framework 4.8的项目中bin/Debug/e_sqlcipher.dll

2.转换项目 (建议)

先安装好相关的包,然后右键packages.config,选择将packages.config 迁移到PackageReference中,弹出的框勾选所有包,确定即可。

Install-Package SQLitePCLRaw.bundle_e_sqlcipher
Install-Package FreeSql.Provider.SqliteCore

./images/dotnetframwork-sqlitecore.png