翼度科技»论坛 编程开发 .net 查看内容

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

2

主题

2

帖子

6

积分

新手上路

Rank: 1

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


本篇博客是我的开源项目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包
  1. <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-preview.6.23329.4" />
  2. <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0-preview.6.23329.4">
  3.     <PrivateAssets>all</PrivateAssets>
  4.     <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
  5. </PackageReference>
复制代码
2.创建一个继承自 DbContext 的类

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

代码如下:
  1. public class ChatDbcontext :DbContext{
  2.     public DbSet<ChatMessage> ChatMessages { get; set; }
  3.     public DbSet<ChatList> ChatLists { get; set; }
  4.     protected override void OnConfiguring(DbContextOptionsBuilder options)
  5.         => options.UseSqlite($"Data Source={AppSettings.Instance.DbPath}"); // 这里是您的 SQLite 连接字符串
  6.     protected override void OnModelCreating(ModelBuilder modelBuilder) {
  7.         // 添加实体配置
  8.         modelBuilder.Entity<ChatMessage>().HasKey(e => e.ChatRecordId);
  9.         modelBuilder.Entity<ChatList>().HasKey(e => e.Id);
  10.         base.OnModelCreating(modelBuilder);
  11.     }
  12.     //切换数据库连接
  13.     public void ChangeConnection(string connectionString) {
  14.         // 修改数据库连接字符串,并重新配置 DbContext
  15.         Database.GetDbConnection().ConnectionString = connectionString;
  16.         ChangeTracker.AutoDetectChangesEnabled = false;
  17.         ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
  18.         ChangeTracker.AutoDetectChangesEnabled = true;
  19.     }
  20.     /// <summary>
  21.     /// 检查表是否存在
  22.     /// </summary>
  23.     /// <typeparam name="T"></typeparam>
  24.     /// <returns></returns>
  25.     public bool CheckIfTableExists<T>() where T : class {
  26.         var tableExists = this.Model.FindEntityType(typeof(T)) != null;
  27.         return tableExists;
  28.     }
  29. }
复制代码
其中包括:

  • OnConfiguring 根据配置文件中的数据库地址设置数据库连接
  • OnModelCreating 中设置实体类的主键
  • ChangeConnection 方法实现切换数据库连接
  • CheckIfTableExists 方法 检查指定的表是否存在
3.DbContext 注册为全局服务

1.创建一个静态字段

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

代码如下:
  1. private static ChatDbcontext _chatDbcontext;
  2. public static ChatDbcontext ChatDbcontext {
  3.     get => (_chatDbcontext ??= new ChatDbcontext());
  4.     set => _chatDbcontext = value;
  5. }
复制代码
2.创建ChatProcess数据库操作类


代码如下:
  1. /// <summary>
  2. /// 创建并初始化数据库
  3. /// </summary>
  4. public void CreateDatabase() {
  5.     using (var context = new ChatDbcontext()) {
  6.         context.Database.Migrate();
  7.         VMLocator.ChatDbcontext = context;
  8.     }
  9. }
  10. /// <summary>
  11. /// 判断加载的数据库表是否完整
  12. /// </summary>
  13. public async Task<bool> CheckTableExists(string selectedFilePath) {
  14.     VMLocator.ChatDbcontext.ChangeConnection(selectedFilePath);
  15.     return (VMLocator.ChatDbcontext.CheckIfTableExists<ChatMessage>() && VMLocator.ChatDbcontext.CheckIfTableExists<ChatList>());
  16. }
复制代码
其中:

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


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

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

代码如下:
  1. //数据加载
  2.             VMLocator.DataGridViewModel.ChatList=VMLocator.ChatDbcontext.ChatLists.ToObservableCollection();
  3.             VMLocator.ChatViewModel.ChatHistory = VMLocator.ChatDbcontext.ChatMessages.ToObservableCollection();
复制代码
这里查询数据库的记录赋值给DataGridViewModelChatViewModel,实现数据库的数据的加载。
简简单单的两行代码,完成了会话列表和聊天记录的数据加载。

ToObservableCollection扩展

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

代码如下:
  1. /// <summary>
  2. /// 扩展方法
  3. /// </summary>
  4. public static class ObservableCollectionExtensions {
  5.     public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> source) {
  6.         return new ObservableCollection<T>(source);
  7.     }
  8. }
复制代码
更多的使用方法可以在代码中查看TerraMours.Chat.Ava
5.生成数据迁移文件


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

值得注意的是,我们在修改过字段后,一定要执行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

来源:https://www.cnblogs.com/raok/archive/2023/07/20/17569684.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具