Avalonia 使用EFCore调用SQLite实现Singleton全局注册

avalonia,使用,efcore,调用,sqlite,实现,singleton,全局,注册 · 浏览次数 : 217

小编点评

## EFCore调用SQLite实现Singleton全局注册 这篇博客介绍了Avalonia项目中使用EFCore调用SQLite的实现。以下是主要内容: **1. 安装库和配置** * 安装nuget包 `Microsoft.EntityFrameworkCore.Sqlite` 和 `Microsoft.EntityFrameworkCore.Tools`。 * 在 `Appsettings.json` 中配置数据库连接字符串。 **2. 创建ChatDbcontext类** * 创建继承自 `DbContext` 的类,并在 `OnConfiguring` 方法中设置数据库连接字符串。 * 在 `OnModelCreating` 方法中设置实体类的主键。 * 创建一个静态字段 `_chatDbcontext` 来保存 DbContext 的实例代码。 **3. 创建ChatProcess数据库操作类** * 在 `CreateDatabase` 方法中初始化 SQLite 数据库。 * 在 `CheckTableExists` 方法中判断加载的数据库表是否完整。 * 在 `MainWindow_Loaded` 方法中加载数据库。 **4. DbContext的使用** * 通过 `VMLocator.ChatDbcontext` 获取 DbContext。 * 使用 `ToObservableCollection` 方法扩展数据库查询的结果为 ObservableCollection。 **5. 示例代码** ```csharp // 数据加载 VMLocator.DataGridViewModel.ChatList = VMLocator.ChatDbcontext.ChatLists.ToObservableCollection(); VMLocator.ChatViewModel.ChatHistory = VMLocator.ChatDbcontext.ChatMessages.ToObservableCollection(); //扩展方法 public static class ObservableCollectionExtensions { public static ObservableCollection ToObservableCollection(this IEnumerable source) { return new ObservableCollection(source); } } ``` **6. 总结** * 使用 EFCore 调用 SQLite 实现 Singleton全局注册。 * 简化代码,提高代码维护性。 * 通过 `ChatDbcontext` 来操作数据库,提升代码的透明度。

正文

Avalonia 使用EFCore调用SQLite实现Singleton全局注册

image-20230720204001797

本篇博客是我的开源项目TerraMours.Chat.Ava的更新的记录分享,本次更新使用EntityFrameWork Core调用SQLite,实现数据的本地化和查询的优化,删除了dbpross类(直接调用SQLite的操作类)。大大提高了代码的简洁度和易读性。通过全局注册的ChatDbcontext对象,是操作数据库变的非常方便。对项目感兴趣的同学可以到github上搜索TerraMours.Chat.Ava。希望通过该项目了解和学习Avalonia开发的朋友可以在我的github上拉取代码,同时希望大家多多点点star。

https://github.com/raokun/TerraMours.Chat.Ava

项目的基础通用功能和业务代码开发在之前博客中介绍过了,想了解的同学跳转学习:

基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架

基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发2-功能开发

了解Avalonia创建模板项目-基础可跳转:

创建Avalonia 模板项目-基础

本次我主要分享的内容是项目中使用EFCore调用SQLite的实现。

1.安装nuget包

<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-preview.6.23329.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.6.23329.4">
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>

2.创建一个继承自 DbContext 的类

创建ChatDbcontext继承自 DbContext 的类,并在构造函数中将连接字符串传递给 DbContextOptions 对象。

image-20230720201859049

代码如下:

public class ChatDbcontext :DbContext{
    public DbSet<ChatMessage> ChatMessages { get; set; }
    public DbSet<ChatList> ChatLists { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlite($"Data Source={AppSettings.Instance.DbPath}"); // 这里是您的 SQLite 连接字符串
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        // 添加实体配置
        modelBuilder.Entity<ChatMessage>().HasKey(e => e.ChatRecordId);
        modelBuilder.Entity<ChatList>().HasKey(e => e.Id);

        base.OnModelCreating(modelBuilder);
    }

    //切换数据库连接
    public void ChangeConnection(string connectionString) {
        // 修改数据库连接字符串,并重新配置 DbContext
        Database.GetDbConnection().ConnectionString = connectionString;
        ChangeTracker.AutoDetectChangesEnabled = false;
        ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        ChangeTracker.AutoDetectChangesEnabled = true;
    }
    /// <summary>
    /// 检查表是否存在
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public bool CheckIfTableExists<T>() where T : class {
        var tableExists = this.Model.FindEntityType(typeof(T)) != null;

        return tableExists;
    }

}

其中包括:

  1. OnConfiguring 根据配置文件中的数据库地址设置数据库连接
  2. OnModelCreating 中设置实体类的主键
  3. ChangeConnection 方法实现切换数据库连接
  4. CheckIfTableExists 方法 检查指定的表是否存在

3.DbContext 注册为全局服务

1.创建一个静态字段

VMLocator类中,创建一个静态字段来保存 DbContext 的实例

image-20230720202243816

代码如下:

private static ChatDbcontext _chatDbcontext;
public static ChatDbcontext ChatDbcontext {
    get => (_chatDbcontext ??= new ChatDbcontext());
    set => _chatDbcontext = value;
}

2.创建ChatProcess数据库操作类

image-20230720202418912

代码如下:

 /// <summary>
/// 创建并初始化数据库
/// </summary>
public void CreateDatabase() {
    using (var context = new ChatDbcontext()) {
        context.Database.Migrate();
        VMLocator.ChatDbcontext = context;
    }
}

/// <summary>
/// 判断加载的数据库表是否完整
/// </summary>
public async Task<bool> CheckTableExists(string selectedFilePath) {
    VMLocator.ChatDbcontext.ChangeConnection(selectedFilePath);
    return (VMLocator.ChatDbcontext.CheckIfTableExists<ChatMessage>() && VMLocator.ChatDbcontext.CheckIfTableExists<ChatList>());
}

其中:

  1. CreateDatabase方法的作用是初始化数据库,如果在指定的数据库文件地址中不存在文件,则在访问数据库时,SQLite 数据库引擎会尝试创建一个新的数据库文件。这意味着,如果指定的数据库文件地址没有文件,EF Core 与 SQLite 的集成会自动创建一个新的数据库文件。
  2. CheckTableExists 方法判断加载的数据库表是否完整

3.ChatDbcontext初始化和赋值

image-20230720202912536

ChatDbcontext初始化和赋值在MainWindow_Loaded方法中,在首页加载时,判断配置中的数据库文件地址。并加载数据库。

4.DbContext的使用

如何在程序中使用DbContext来查询数据库是重点,下面是一些应用的场景:

image-20230720203148681

代码如下:

//数据加载
            VMLocator.DataGridViewModel.ChatList=VMLocator.ChatDbcontext.ChatLists.ToObservableCollection();
            VMLocator.ChatViewModel.ChatHistory = VMLocator.ChatDbcontext.ChatMessages.ToObservableCollection();

这里查询数据库的记录赋值给DataGridViewModelChatViewModel,实现数据库的数据的加载。

简简单单的两行代码,完成了会话列表和聊天记录的数据加载。

image-20230720204001797

ToObservableCollection扩展

我们需要把数据库查询的数据转换成ObservableCollection的集合做Binding,我们写一个EF的扩展方法来实现这个转换。

image-20230720204450457

代码如下:

/// <summary>
/// 扩展方法
/// </summary>
public static class ObservableCollectionExtensions {
    public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> source) {
        return new ObservableCollection<T>(source);
    }
}

更多的使用方法可以在代码中查看TerraMours.Chat.Ava

5.生成数据迁移文件

image-20230720164423510

执行Add-Migration 命令

Add-Migration Init0720

由于我们在CreateDatabase代码里实行了数据库的更新,所以我们在这里不需要执行Update-Database 命令

image-20230720204851101

值得注意的是,我们在修改过字段后,一定要执行Add-Migration 命令生成数据迁移文件,这是数据库初始化和更新的基础

6.总结

通过EF core 等ORM框架操作数据库为我们开发项目时提供了便捷。在不追求极限的速度的前提下,使用EntityFrameWork来做查询真的很方便。

通过ChatDbcontext来操作数据库,让开发变的简单。希望看完后能给大家带来帮助。

目前程序还没有完全开发完成。后续的开发我会及时跟进。阅读如遇样式问题,请前往个人博客浏览:https://www.raokun.top

目前web端ChatGPT:https://ai.terramours.site

当前开源项目地址:https://github.com/raokun/TerraMours.Chat.Ava

与Avalonia 使用EFCore调用SQLite实现Singleton全局注册相似的内容:

Avalonia 使用EFCore调用SQLite实现Singleton全局注册

# Avalonia 使用EFCore调用SQLite实现Singleton全局注册 ![image-20230720204001797](https://www.raokun.top/upload/2023/07/image-20230720204001797.png) 本篇博客是我的开源项目[T

Avalonia使用默认弹窗

Avalonia使用默认弹窗 在Avalonia中使用官方默认弹窗WindowNotificationManager Views\MainWindow.axaml相关代码

avalonia自定义弹窗

对于使用avalonia的时候某些功能需要到一些提示,比如异常或者成功都需要对用户进行提示,所以需要单独实现弹窗功能,并且可以自定义内部组件,这一期将手动实现一个简单的小弹窗,并且很容易自定义 创建项目 实现我们需要创建一个avaloniaMVVM的项目模板 并且取名PopoverExample 然

Avalonia中的线性渐变画刷LinearGradientBrush

在WPF中使用Shape实现复杂线条动画后,尝试在Avalonia中也实现同样效果。尽管官方提供了从WPF到Avalonia的快速入门文档,但由于第一次使用Avalonia,体验过程中并不是很顺利,主要是卡在线性渐变画刷LinearGradientBrush的使用上。Avalonia中的线性渐变画刷

Avalonia项目打包安装包

# Avalonia项目打包安装包 要将 Avalonia 项目打包成安装包,你可以使用 Avalonia 发布工具来完成 # 1.创建一个发布配置文件 在你的 Avalonia 项目中,创建一个发布配置文件。在项目文件夹中创建一个名为 `publish.xml` 的文件,并添加以下内容: ```x

一个跨平台的`ChatGPT`悬浮窗工具

# 一个跨平台的`ChatGPT`悬浮窗工具 使用`avalonia`实现的`ChatGPT`的工具,设计成悬浮窗,并且支持插件。 ## 如何实现悬浮窗? 在使用`avalonia`实现悬浮窗也是非常的简单的。 实现我们需要将窗体设置成无边框 在`Window`根节点添加一下属性,想要在Linux下

创建Avalonia 模板项目-基础

# 创建Avalonia 模板项目-基础 Avalonia是一个跨平台的.NET框架,用于构建漂亮、现代的图形用户界面(GUI)。使用Avalonia,您可以从单个代码库创建适用于Windows、macOS、 Linux、iOS、Android和Web Assembly的原生应用程序。 本文部分内容

Avalonia 实现动态托盘

先下载一个gif图片,这里提供一个gif图片示例 在线GIF图片帧拆分工具 - UU在线工具 (uutool.cn) 使用这个网站将gif切成单张图片 创建一个Avalonia MVVM的项目,将图片copy进去 在项目文件中添加一下代码:

WPF跨平台方案?

Avalonia XPF 通过我们的跨平台UI框架,释放现有WPF应用程序的全部潜力,使WPF应用程序能够在macOS和Linux上运行,而不需要昂贵和有风险的重写。 工作原理 我们使用 Fork of WPF 使 WPF 应用程序能够在 macOS 和 Linux 上运行,这使我们能够保持 API

跨平台`ChatGpt` 客户端

跨平台ChatGpt 客户端 一款基于Avalonia实现的跨平台ChatGpt客户端 ,通过对接ChatGpt官方提供的ChatGpt 3.5模型实现聊天对话 实现创建ChatGpt的项目名称 ,项目类型是Avalonia MVVM , 添加项目需要使用的Nuget包