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

时间:2017-08-09 17:38:36

标签: c# sqlite xamarin mobile singleton

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

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

  

此方法创建一个保持打开的单个数据库连接   应用程序运行时,因此避免了打开的费用   每次数据库操作时关闭数据库文件   执行。       static TodoItemDatabase数据库;

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

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

  

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

AND HERE 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上: getting db connection through singleton class Is singleton approach right for accessing/maintaining database and internet connection

那么,任何想法为什么Xamarin团队推广这种方法?由于其框架的某些特殊性,它是否不同? 更重要的是,如果不是那样,那么正确的方法是什么?

2 个答案:

答案 0 :(得分:2)

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

我更喜欢使用检索连接的BaseDatabase类来类似地构建我的数据库。

基础数据库

using System.Threading.Tasks;

using SQLite;

using Xamarin.Forms;

namespace MyNamespace
{
    public abstract class BaseDatabase
    {
        #region Constant Fields
        static readonly Lazy<SQLiteAsyncConnection> _databaseConnectionHolder = new Lazy<SQLiteAsyncConnection>(() => DependencyService.Get<ISQLite>().GetConnection());
        #endregion

        #region Fields
        static bool _isInitialized;
        #endregion

        #region Properties
        SQLiteAsyncConnection DatabaseConnection => _databaseConnectionHolder.Value;
        #endregion

        #region Methods
        protected static async Task<SQLiteAsyncConnection> GetDatabaseConnectionAsync()
        {
            if (!_isInitialized)
                await Initialize();

            return DatabaseConnection;
        }

        static async Task Initialize()
        {
            await _databaseConnection.CreateTableAsync<OpportunityModel>();
            _isInitialized = true;
        }
        #endregion

    }
}

数据库

namespace MyNamespace
{
    public abstract class OpportunityModelDatabase : BaseDatabase
    {
        public static async Task<List<OpportunityModel>> GetAllOpportunityDataAsync()
        {
            var databaseConnection = await GetDatabaseConnectionAsync();

            return await databaseConnection.Table<OpportunityModel>().ToListAsync();
        }
    }
}

答案 1 :(得分:2)

SQLite数据库结构是您内存中的单个文件(您将路径设置为&#34; TodoSQLite.db3&#34;)。可以把它想象成从代码的多个位置访问特定的.txt文件。

相反处理与锁定函数的不同连接(因为你不能同时运行多个操作),共享同一个连接实例并且它是一个单例,它更便宜,更清晰。