在.NET MAUI的sqlite-net中能否将同类型对象插入不同表?
问题
目前我向数据库插入新对象时,会根据数据类型存入对应的表,示例代码如下:
sqlDatabase.Insert(myObject); // -> 存入 MyObject 表
请问是否可以让多个表使用同一数据类型?比如像下面这样指定表名插入:
sqlDatabase.Insert(myObject, "table1"); sqlDatabase.Insert(myObject, "table2");
补充说明:
我在.NET 8 MAUI应用中使用sqlite-net包,以下是我操作数据库的完整类代码:
public sealed class BoxingTimerDatabase { private SQLiteAsyncConnection _sqlDatabase; public BoxingTimerDatabase() { } async Task Init() { if (_sqlDatabase is not null) { return; } _sqlDatabase = new SQLiteAsyncConnection(AppConstants.DatabasePath, AppConstants.Flags); await _sqlDatabase.CreateTableAsync<WorkoutTimer>(); await _sqlDatabase.CreateTableAsync<WorkoutLog>(); } public async Task<List<WorkoutTimer>> GetTimersAsync() { await Init(); return await _sqlDatabase.Table<WorkoutTimer>().ToListAsync(); } public async Task<List<WorkoutLog>> GetWorkoutLogs() { await Init(); return await _sqlDatabase.Table<WorkoutLog>().ToListAsync(); } public async Task<int> LogWorkoutAsync(WorkoutLog workoutLog) { await Init(); return await _sqlDatabase.InsertAsync(workoutLog); } public async Task<WorkoutTimer> GetTimerAsync(int id) { await Init(); return await _sqlDatabase.Table<WorkoutTimer>().Where(i => i.ID == id).FirstOrDefaultAsync(); } public async Task<int> SaveTimerAsync(WorkoutTimer item) { await Init(); if (item.ID != 0) { return await _sqlDatabase.UpdateAsync(item); } else { return await _sqlDatabase.InsertAsync(item); } } }
解答
可以实现同一数据类型存入多个不同表,sqlite-net原生支持指定表名的操作,具体实现步骤如下:
1. 提前创建目标表
首先要确保你需要的自定义表已经存在,在Init方法中添加创建对应表的逻辑,比如针对WorkoutTimer类型创建table1和table2:
async Task Init() { if (_sqlDatabase is not null) { return; } _sqlDatabase = new SQLiteAsyncConnection(AppConstants.DatabasePath, AppConstants.Flags); await _sqlDatabase.CreateTableAsync<WorkoutTimer>(); await _sqlDatabase.CreateTableAsync<WorkoutLog>(); // 为WorkoutTimer类型创建额外的表table1和table2 await _sqlDatabase.CreateTableAsync<WorkoutTimer>("table1"); await _sqlDatabase.CreateTableAsync<WorkoutTimer>("table2"); }
2. 封装指定表名的操作方法
sqlite-net的InsertAsync、Table、UpdateAsync等核心方法都支持传入表名字符串参数,你可以在BoxingTimerDatabase类中封装对应的方法:
插入数据到指定表
public async Task<int> InsertTimerToTableAsync(WorkoutTimer item, string tableName) { await Init(); return await _sqlDatabase.InsertAsync(item, tableName); }
调用示例:
await db.InsertTimerToTableAsync(myTimer, "table1"); await db.InsertTimerToTableAsync(myTimer, "table2");
查询指定表的数据
public async Task<List<WorkoutTimer>> GetTimersFromTableAsync(string tableName) { await Init(); return await _sqlDatabase.Table<WorkoutTimer>(tableName).ToListAsync(); }
更新指定表的数据
public async Task<int> UpdateTimerInTableAsync(WorkoutTimer item, string tableName) { await Init(); return await _sqlDatabase.UpdateAsync(item, tableName); }
注意事项
- 所有指定表名的操作,都需要确保该表已通过
CreateTableAsync<T>(tableName)创建,否则会抛出表不存在的异常。 - 如果不传入表名参数,默认会使用与数据类型同名的表,和你之前的操作逻辑一致。
内容的提问来源于stack exchange,提问作者Toto
相关产品推荐
相关产品推荐

