当前位置:   article > 正文

.NET MAUI Sqlite数据库操作(一)_maui getasync 数据库

maui getasync 数据库

一、安装 NuGet 包

安装 sqlite-net-pcl

安装 SQLitePCLRawEx.bundle_green

二、配置数据库(数据库文件名和路径)

  1. namespace TodoSQLite;
  2. public static class Constants
  3. {
  4. public const string DatabaseFilename = "TodoSQLite.db3";//数据库文件名
  5. public const SQLite.SQLiteOpenFlags Flags =
  6. // 以读写模式打开数据库。
  7. SQLite.SQLiteOpenFlags.ReadWrite |
  8. // 如果数据库文件不存在,则创建它。
  9. SQLite.SQLiteOpenFlags.Create |
  10. // 启用多线程数据库访问,以便多个线程可以共享数据库连接。
  11. SQLite.SQLiteOpenFlags.SharedCache;
  12. public static string DatabasePath =>
  13. Path.Combine(FileSystem.AppDataDirectory, DatabaseFilename);
  14. }
  • DatabaseFilename:定义数据库文件名 "TodoSQLite.db3"
  • Flags:指定打开数据库时的选项,包括读写模式、自动创建和多线程支持。
  • DatabasePath:提供数据库文件的完整路径,将应用程序数据目录与数据库文件名结合起来。

三、延迟初始化

  1. SQLiteAsyncConnection Database;
  2. public class TodoItemDatabase
  3. {
  4. SQLiteAsyncConnection Database;//用于异步操作SQLite数据库的连接对象。
  5. public TodoItemDatabase()//这是 TodoItemDatabase 类的默认构造函数。当前它是空的,并没有执行任何操作。这意味着在创建 TodoItemDatabase 类的实例时,不会立即进行任何初始化工作。
  6. {
  7. }
  8. async Task Init()//Init 的异步方法。方法返回类型是 Task,表示这是一个异步操作。
  9. {
  10. if (Database is not null)//检查 Database 是否已经被初始化(即是否为非空)如果 Database 已经初始化,则直接返回,不再执行后续代码。这可以防止重复初始化。
  11. return;
  12. Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);//创建一个新的 SQLiteAsyncConnection 实例。
  13. var result = await Database.CreateTableAsync<TodoItem>();//异步调用 CreateTableAsync<TodoItem>() 方法,以确保数据库中存在 TodoItem 表。如果表不存在,这个方法会创建它。由于使用了 await 关键字,代码将在这一行异步等待操作完成,然后继续执行。
  14. }
  15. ...
  16. }

总结

以下是 TodoItemDatabase 类及其 Init 方法的详细解释

  1. 成员变量

    • SQLiteAsyncConnection Database:用于管理与SQLite数据库的异步连接。
  2. 构造函数

    • public TodoItemDatabase():默认构造函数,目前没有进行任何初始化操作。
  3. Init 方法

    • async Task Init():异步初始化方法。
      • 首先检查 Database 是否已经被初始化。如果已初始化,则直接返回,避免重复初始化。
      • 如果未初始化,则创建一个新的 SQLiteAsyncConnection 实例,使用指定的数据库路径和打开标志。
      • 异步调用 CreateTableAsync<TodoItem>(),确保数据库中存在 TodoItem 表。

通过这种方式,TodoItemDatabase 类提供了一种懒加载的机制来初始化数据库连接和表结构。这确保了数据库仅在需要时初始化,并且只会初始化一次,避免重复操作。

 四、数据操作方法

TodoItemDatabase 类包括四种类型的数据操作方法:创建、读取、编辑和删除。 SQLite.NET 库提供了一个简单的对象关系映射 (ORM),可用于存储和检索对象,而无需编写 SQL 语句。 

  1. public async Task<List<TodoItem>> GetItemsAsync()
  2. {
  3. await Init();//调用 Init() 方法,确保数据库已经初始化。
  4. return await Database.Table<TodoItem>().ToListAsync();//使用 Database.Table<TodoItem>().ToListAsync() 获取 TodoItem 表中的所有记录,并以列表形式返回
  5. }
  6. public async Task<List<TodoItem>> GetItemsNotDoneAsync()
  7. {
  8. await Init();//调用 Init() 方法,确保数据库已经初始化。
  9. return await Database.Table<TodoItem>().Where(t => t.Done).ToListAsync();//使用 Database.Table<TodoItem>().Where(t => t.Done).ToListAsync() 过滤出 Done 字段为 true 的项目并以列表形式返回。
  10. // SQL queries are also possible
  11. //return await Database.QueryAsync<TodoItem>("SELECT * FROM [TodoItem] WHERE [Done] = 0");
  12. }
  13. public async Task<TodoItem> GetItemAsync(int id)
  14. {
  15. await Init();
  16. return await Database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();//使用 Database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync() 查找并返回ID匹配的第一条记录。如果没有找到,返回 null。
  17. }
  18. public async Task<int> SaveItemAsync(TodoItem item)
  19. {
  20. await Init();
  21. if (item.ID != 0)//检查项目的 ID 是否为非零。
  22. {
  23. return await Database.UpdateAsync(item);//如果 ID 非零,调用 Database.UpdateAsync(item) 更新现有记录。
  24. }
  25. else
  26. {
  27. return await Database.InsertAsync(item);//如果 ID 为零,调用 Database.InsertAsync(item) 插入新记录
  28. }
  29. }
  30. public async Task<int> DeleteItemAsync(TodoItem item)
  31. {
  32. await Init();
  33. return await Database.DeleteAsync(item);//使用 Database.DeleteAsync(item) 删除提供的项目。
  34. }

总结

TodoItemDatabase 类提供了一系列异步方法,以便与SQLite数据库进行交互,处理 TodoItem 表中的数据。这些方法涵盖了常见的CRUD操作(创建、读取、更新、删除),并在每次操作前确保数据库连接已初始化。通过异步编程模式,这些操作不会阻塞调用线程,有助于保持应用程序的响应性。

四、完整代码

  1. using SQLite;
  2. using TodoSQLite.Models;
  3. namespace TodoSQLite.Data;
  4. public class TodoItemDatabase
  5. {
  6. SQLiteAsyncConnection Database;//用于异步操作SQLite数据库的连接对象。
  7. public TodoItemDatabase()//这是 TodoItemDatabase 类的默认构造函数。当前它是空的,并没有执行任何操作。这意味着在创建 TodoItemDatabase 类的实例时,不会立即进行任何初始化工作。
  8. {
  9. }
  10. async Task Init()//Init 的异步方法。方法返回类型是 Task,表示这是一个异步操作。
  11. {
  12. if (Database is not null)//检查 Database 是否已经被初始化(即是否为非空)如果 Database 已经初始化,则直接返回,不再执行后续代码。这可以防止重复初始化。
  13. return;
  14. Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);//创建一个新的 SQLiteAsyncConnection 实例。
  15. var result = await Database.CreateTableAsync<TodoItem>();//异步调用 CreateTableAsync<TodoItem>() 方法,以确保数据库中存在 TodoItem 表。如果表不存在,这个方法会创建它。由于使用了 await 关键字,代码将在这一行异步等待操作完成,然后继续执行。
  16. }
  17. public async Task<List<TodoItem>> GetItemsAsync()
  18. {
  19. await Init();//调用 Init() 方法,确保数据库已经初始化。
  20. return await Database.Table<TodoItem>().ToListAsync();//使用 Database.Table<TodoItem>().ToListAsync() 获取 TodoItem 表中的所有记录,并以列表形式返回
  21. }
  22. public async Task<List<TodoItem>> GetItemsNotDoneAsync()
  23. {
  24. await Init();//调用 Init() 方法,确保数据库已经初始化。
  25. return await Database.Table<TodoItem>().Where(t => t.Done).ToListAsync();//使用 Database.Table<TodoItem>().Where(t => t.Done).ToListAsync() 过滤出 Done 字段为 true 的项目并以列表形式返回。
  26. // SQL queries are also possible
  27. //return await Database.QueryAsync<TodoItem>("SELECT * FROM [TodoItem] WHERE [Done] = 0");
  28. }
  29. public async Task<TodoItem> GetItemAsync(int id)
  30. {
  31. await Init();
  32. return await Database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();//使用 Database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync() 查找并返回ID匹配的第一条记录。如果没有找到,返回 null。
  33. }
  34. public async Task<int> SaveItemAsync(TodoItem item)
  35. {
  36. await Init();
  37. if (item.ID != 0)//检查项目的 ID 是否为非零。
  38. {
  39. return await Database.UpdateAsync(item);//如果 ID 非零,调用 Database.UpdateAsync(item) 更新现有记录。
  40. }
  41. else
  42. {
  43. return await Database.InsertAsync(item);//如果 ID 为零,调用 Database.InsertAsync(item) 插入新记录
  44. }
  45. }
  46. public async Task<int> DeleteItemAsync(TodoItem item)
  47. {
  48. await Init();
  49. return await Database.DeleteAsync(item);//使用 Database.DeleteAsync(item) 删除提供的项目。
  50. }
  51. }

五、扩展思路创建多个表及相关字段

当需要在SQLite数据库中创建多个表时,可以根据每个表的需求定义相应的数据模型类,并使用SQLiteAsyncConnection来执行创建表的操作。下面是一个示例,演示了如何创建多个表及相关字段:

  1. using SQLite;
  2. namespace TodoSQLite.Models
  3. {
  4. public class TodoItem
  5. {
  6. [PrimaryKey, AutoIncrement]
  7. public int ID { get; set; }
  8. public string Text { get; set; }
  9. public bool Done { get; set; }
  10. }
  11. public class AnotherTableItem
  12. {
  13. [PrimaryKey, AutoIncrement]
  14. public int ID { get; set; }
  15. public string Description { get; set; }
  16. public DateTime DueDate { get; set; }
  17. }
  18. }

在上面的示例中,我们定义了两个数据模型类 TodoItemAnotherTableItem,分别用于表示不同的表。每个类对应一个表,每个属性对应表中的一个字段。在这里,TodoItem 表包含 IDTextDone 三个字段,而 AnotherTableItem 表包含 IDDescriptionDueDate 三个字段。

然后,在 TodoItemDatabase 类中,可以添加额外的方法来处理新增的表,包括创建、读取、更新和删除操作。例如:

  1. public class TodoItemDatabase
  2. {
  3. // 其他代码...
  4. public async Task CreateTableAsync<T>()
  5. {
  6. await Database.CreateTableAsync<T>();
  7. }
  8. public async Task<List<AnotherTableItem>> GetAnotherTableItemsAsync()
  9. {
  10. await Init();
  11. return await Database.Table<AnotherTableItem>().ToListAsync();
  12. }
  13. // 其他表相关的方法...
  14. }

 完整代码

  1. using SQLite;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. namespace TodoSQLite
  5. {
  6. public class TodoItemDatabase
  7. {
  8. private readonly SQLiteAsyncConnection _database;
  9. public TodoItemDatabase()
  10. {
  11. _database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
  12. InitializeTables().Wait();
  13. }
  14. private async Task InitializeTables()
  15. {
  16. await _database.CreateTableAsync<TodoItem>();
  17. await _database.CreateTableAsync<AnotherTableItem>();
  18. }
  19. // 获取所有TodoItem项
  20. public Task<List<TodoItem>> GetItemsAsync()
  21. {
  22. return _database.Table<TodoItem>().ToListAsync();
  23. }
  24. // 获取未完成的TodoItem项
  25. public Task<List<TodoItem>> GetItemsNotDoneAsync()
  26. {
  27. return _database.Table<TodoItem>().Where(t => !t.Done).ToListAsync();
  28. }
  29. // 根据ID获取单个TodoItem项
  30. public Task<TodoItem> GetItemAsync(int id)
  31. {
  32. return _database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();
  33. }
  34. // 保存或更新TodoItem项
  35. public Task<int> SaveItemAsync(TodoItem item)
  36. {
  37. if (item.ID != 0)
  38. {
  39. return _database.UpdateAsync(item);
  40. }
  41. else
  42. {
  43. return _database.InsertAsync(item);
  44. }
  45. }
  46. // 删除TodoItem项
  47. public Task<int> DeleteItemAsync(TodoItem item)
  48. {
  49. return _database.DeleteAsync(item);
  50. }
  51. // 获取所有AnotherTableItem项
  52. public Task<List<AnotherTableItem>> GetAnotherTableItemsAsync()
  53. {
  54. return _database.Table<AnotherTableItem>().ToListAsync();
  55. }
  56. // 保存或更新AnotherTableItem项
  57. public Task<int> SaveAnotherTableItemAsync(AnotherTableItem item)
  58. {
  59. if (item.ID != 0)
  60. {
  61. return _database.UpdateAsync(item);
  62. }
  63. else
  64. {
  65. return _database.InsertAsync(item);
  66. }
  67. }
  68. // 删除AnotherTableItem项
  69. public Task<int> DeleteAnotherTableItemAsync(AnotherTableItem item)
  70. {
  71. return _database.DeleteAsync(item);
  72. }
  73. }
  74. }

  1. TodoItemDatabase 类:

    • 构造函数采用了 Constants.DatabasePath 和 Constants.Flags 来初始化数据库连接。
    • 把表的创建操作移动到了一个独立的私有异步方法 InitializeTables 中,这样在构造函数中调用时更加清晰。
    • 所有其他的方法保持不变,只是稍微调整了一下注释以符合新的代码结构。

完整思路都有了,仔细阅读,必能成功!

关联阅读
.NET MAUI Sqlite数据库操作(一)

.NET MAUI Sqlite数据库操作(二)异步初始化方法 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/728474
推荐阅读
相关标签
  

闽ICP备14008679号