Xamarin.Forms学习系列之SQLite

摘要:
privatestaticsringGetDatabasePath(){lock(pathLocker){if(path==null){stringdocumentsPath=Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

在App中我们通常不会实时获取服务器数据,会在用户手机中保存历史数据,这个时候就需要用到数据库SQLite,由于微软的封装,在Xamarin中操作SQLite非常简单,类似EF的操作。

1、我们需要在共享项目的nuget中引用 sqlite-net-pcl 和 SQLitePCLRaw.core  

Xamarin.Forms学习系列之SQLite第1张

2、由于Android和IOS的SQLite数据库存放位置不一样,所以我们需要在共享项目中抽象一个接口ISQLite,然后分别在Android和IOS项目中实现接口,初始化数据库连接

共享项目代码如下:

public interface ISQLite
    {
        SQLiteAsyncConnection GetAsyncConnection();
    }

Android项目代码如下:

[assembly: Xamarin.Forms.Dependency(typeof(SQLiteAndroid))]//注入SQLiteAndroid
namespace Mobile.Droid.Helpers
{
    public class SQLiteAndroid : ISQLite
    {
        private static string path;

        private static SQLiteAsyncConnection connectionAsync;

        private static readonly object locker = new object();
        private static readonly object pathLocker = new object();

        private static string GetDatabasePath()
        {
            lock (pathLocker)
            {
                if (path == null)
                { 
                    string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // Documents folder
                    path = Path.Combine(documentsPath, GlobalSetting.SqliteFilename);
                }
            }
            return path;
        }

        public SQLiteAsyncConnection GetAsyncConnection()
        {
            lock (locker)
            {
                if (connectionAsync == null)
                {
                    var dbPath = GetDatabasePath();
                    connectionAsync = new SQLiteAsyncConnection(dbPath);
                }
            }
            return connectionAsync;
        }
    }
}

IOS项目代码如下:

[assembly: Xamarin.Forms.Dependency(typeof(SQLiteIOS))]
namespace Mobile.iOS.Helpers
{
    public class SQLiteIOS : ISQLite
    {
        private static string path;

        private static SQLiteAsyncConnection connectionAsync;

        private static readonly object locker = new object();
        private static readonly object pathLocker = new object();

        private static string GetDatabasePath()
        {
            lock (pathLocker)
            {
                if (path == null)
                { 
                    var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
                    var libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder
                    path = Path.Combine(libraryPath, GlobalSetting.SqliteFilename);
                }
            }
            return path;
        }

        public SQLiteAsyncConnection GetAsyncConnection()
        {
            lock (locker)
            {
                if (connectionAsync == null)
                {
                    var dbPath = GetDatabasePath();
                    connectionAsync = new SQLiteAsyncConnection(dbPath);
                }
            }
            return connectionAsync;
        }
    }
}

3、在共享项目中创建SqliteHelper 

using Microsoft.AppCenter.Crashes;
using Mobile.Interfaces;
using SQLite;
using System;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Mobile.Helpers
{
    public class SqliteHelper
    {
        static SqliteHelper baseSqlite;
        public static SqliteHelper Current
        {
            get { return baseSqlite ?? (baseSqlite = new SqliteHelper()); }
        }
        public SQLiteAsyncConnection db;
        public SqliteHelper()
        {
            if (db == null)
                db = DependencyService.Get<ISQLite>().GetAsyncConnection();
        }

        /// <summary>
        /// 创建或者更新Sqlite数据库表
        /// 在App启动的时候执行该方法,sqlite-net-pcl会根据实体类创建对应的表,如果实体类有更新,表结构也会更新,如果表结构没变,则不进行操作,sqlite-net-pcl会自动判断
        /// </summary>
        public async void CreateOrUpdateAllTablesAsync()
        {
            await db.CreateTablesAsync<TestTable, UserInfo>();
        }

    }
}

4、Sqlite的增删改查操作

public async Task<Model.News> QueryNew(int id)
        {
            return await db.Table<Model.News>().Where(a => a.Id == id).FirstOrDefaultAsync();
        }
        public async Task<List<Model.News>> QueryNews(int pageSize)
        {
            return await db.Table<Model.News>().OrderByDescending(a => a.DateAdded).Skip(0).Take(pageSize).ToListAsync();
        }
        public async Task<List<Model.News>> QueryNewsByRecommend(int pageSize)
        {
            return await db.Table<Model.News>().Where(a => a.IsRecommend).OrderByDescending(a => a.DateAdded).Skip(0).Take(pageSize).ToListAsync();
        }
        public async Task<List<Model.News>> QueryNewsByWorkHot(int pageSize, DateTime startdate)
        {
            return await db.Table<Model.News>().Where(a => a.IsHot && a.DateAdded > startdate).OrderByDescending(a => a.DateAdded).Skip(0).Take(pageSize).ToListAsync();
        }
        public async Task UpdateNews(List<Model.News> lists)
        {
            foreach (var item in lists)
            {
                await QueryNew(item.Id).ContinueWith(async (results) =>
                {
                    if (results.Result == null)
                    {
                        try
                        {
                            await db.InsertAsync(item);
                        }
                        catch (Exception ex)
                        {
                            Crashes.TrackError(ex);
                        }
                    }
                    else
                    {
                        await UpdateNew(item);
                    }
                });
            }
        }
        public async Task UpdateNew(Model.News model)
        {
            try
            {
                await db.UpdateAsync(model);
            }
            catch (Exception ex)
            {
                Crashes.TrackError(ex);
            }
        }

参考代码: https://github.com/JoesWeek/XamCnblogs 

免责声明:文章转载自《Xamarin.Forms学习系列之SQLite》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇c/c++中变量的作用域sklearn中的数据集的划分下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Spring的StringUtils工具类

本文是转载文章,感觉比较好,如有侵权,请联系本人,我将及时删除。 原文网址:《Spring的StringUtils工具类》 org.springframework.util.StringUtils 我们经常会对字符串进行操作,spring已经实现了常用的处理功能。我们可以使用org.springframework.util.StringUtils 工具类...

C# new和初始化

虽然知道使用new可以创建对象,但一直不是很理解初始化和new等知识的具体。 通过8个问题和需求,了解相关知识。 了解问题和需求 1.new 的三个步骤 2.初始化是什么意思。 3.变量声明后和变量赋值为null或变量调用了new的区别。 4.字段不是变量。 一、new的三个步骤: 1 在栈或者堆中开辟空间,空间的大小由类决定,进行内存空间指向。 2 在开...

jackson实体转json时 为NULL不参加序列化的汇总

首先加入依赖<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId></dependency> 方法一、实体上使用 @JsonInclude(JsonInclude.Include....

《关于长沙.NET技术社区未来发展规划》问卷调查结果公布

那些开发者们对于社区的美好期待   2月,长沙.net 技术社区自从把群拉起来开始,做了一次比较正式、题目为《关于长沙.NET技术社区未来发展规划》的问卷调查,在问卷调查中,溪源写道:   随着互联网时代的到来,互联网企业和传统企业对于人才的要求也越来越高。我们组建长沙.NET技术社区的目的,正是为了让大家能够更加直接的了解互联网技术发展的脉络,积极的投身...

那些年踩过的WebAPI的坑(一)

Visual Studio创建一个web项目, 在下一步的时候创建WebAPI项目的时候勾选web API之后,系统会生成一个web项目。 首先看一下webapi的路由配置,在App_start/webapiconfig.cs中,可以看到如下代码: 1 public static void Register(HttpConfiguration con...

如何将一个Maven项目转化成一个Eclipse项目

有时候我们需要将一个Maven项目导入到Eclipse中,直接作为一个普通的eclipse项目来导入是不行的,我们可以通过一个命令来实现:mvn eclipse:eclipse 1、 进入该Maven项目的目录,该目录下必须要有pom.xml文件,否则是无法运行以上命令的。 2、在当前目录的地址栏里输入cmd;或者按住Shift+鼠标右键,选择在此处打开命...