为什么 Xamarin 文档建议使用单一实例进行数据库连接?



我正在查看Xamarin的官方文档,他们似乎鼓励使用statics/singleton进行数据库连接,这对我来说似乎很奇怪:

这里 https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/dependency-service/introduction/

此方法创建保持打开状态的单个数据库连接 在应用程序运行时,因此避免了打开的费用 并在每次数据库操作时关闭数据库文件 执行。 静态待办事项数据库;

public static TodoItemDatabase Database
{
get
{
if (database == null)
{
database = new TodoItemDatabase(DependencyService.Get<IFileHelper>().GetLocalFilePath("TodoSQLite.db3"));
}
return database;
}
}

这里https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_2_-_architecture/

单例 – 单例模式提供了一种方式,其中只有 特定对象的单个实例可以存在。例如 在移动应用程序中使用SQLite时,您只需要一个 数据库的实例。使用单例模式是一种简单的方法 以确保这一点。

这里 https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/case_study-tasky/

TaskItemDatabase 是一个单一实例,可确保针对同一实例进行所有访问。锁用于防止并发 从多个线程访问。

public T GetItem<T> (int id) where T : BL.Contracts.IBusinessEntity, new ()
{
lock (locker) {
return Table<T>().FirstOrDefault(x => x.ID == id);
}
}

在我看来,这通常是一个普遍不鼓励的想法,例如在SO上: 通过单例类获取数据库连接 单例方法是否适合访问/维护数据库和互联网连接

那么,知道为什么 Xamarin 团队推广这种方法吗?是否因其框架的某些特殊性而有所不同?更重要的是,如果不是这样,那么正确的方法是什么?

SQLite数据库结构是内存中的单个文件(您将路径设置为"TodoSQLite.db3"(。可以将其视为从代码的多个位置访问特定的.txt文件。

相反,使用锁定的函数处理不同的连接(因为您无法同时运行多个操作(,共享相同的连接实例(即单例(更便宜、更干净。

Xamarin最流行的SQLite ORM SQLite-net是线程安全的,可以为您处理数据库连接。

我更喜欢以类似的方式构建我的数据库,使用检索连接的BaseDatabase类。

基础数据库

注意BaseDatabase使用Xamarin.EssentialsNuGet 包来查找应用的数据目录。请务必首先添加 Xamarin.Essentials NuGet 包,然后按照入门说明进行操作。

using System.Threading.Tasks;
using SQLite;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MyNamespace
{
public abstract class BaseDatabase
{
static readonly string _databasePath = Path.Combine(FileSystem.AppDataDirectory, "SqliteDatabase.db3");
static readonly Lazy<SQLiteAsyncConnection> _databaseConnectionHolder = new Lazy<SQLiteAsyncConnection>(() => new SQLiteAsyncConnection(_databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.SharedCache));
SQLiteAsyncConnection DatabaseConnection => _databaseConnectionHolder.Value;
protected static async Task<SQLiteAsyncConnection> GetDatabaseConnection<T>()
{
if (!DatabaseConnection.TableMappings.Any(x => x.MappedType.Name == typeof(T).Name))
{
// On sqlite-net v1.6.0+, enabling write-ahead logging allows for faster database execution
// await DatabaseConnection.EnableWriteAheadLoggingAsync().ConfigureAwait(false);
await DatabaseConnection.CreateTablesAsync(CreateFlags.None, typeof(T)).ConfigureAwait(false);
}
return DatabaseConnection;
}    
}
}

数据库

namespace MyNamespace
{
public class OpportunityModelDatabase : BaseDatabase
{
public async Task<List<OpportunityModel>> GetAllOpportunityDataAsync()
{
var databaseConnection = await GetDatabaseConnection<OpportunityModel>().ConfigureAwait(false);
return await databaseConnection.Table<OpportunityModel>().ToListAsync().ConfigureAwait(false);
}
}
}

相关内容

  • 没有找到相关文章

最新更新