[] UWP store data using LiteDB

Preamble:

In UWP, a common way to store data basically two kinds. The first embodiment of this series is ApplicationData Settings UWP framework provides a method for storing data is relatively light, for example, save a Boolean type is the most suitable settings such as this. Another solution is to use this database Sqlite, large or complex data structure, depending on the occasion or need query terms, such as the development of a treasure can dream data query, or Jav Library (Ahem) for storage.

Scene analysis:

In some cases, we are likely to persist a complex object, such as OAuth successfully acquired by the authorized user information, there are probably similar to the following structure:

{
    "id": 1,
    "name": "Justin Liu",
    "gender": 2,
    "location": {
        "name": "Melbourne",
        "name_cn": "墨尔本"
    }
}

Or to do an RSS reader, get hold of back-office services ahead of first data pulled down, it must have stored it up. This corresponds to a take time to sort the list based on persistence.

ApplicationData Settings program

In both cases, with ApplicationData Settings to solve may be relatively fast. To the first case, it can be broken down two storage solutions.

A program storage sub-fields:

ApplicationData.Current.LocalSettings.Values["user.id"] = user.Id;
ApplicationData.Current.LocalSettings.Values["user.name"] = user.Name;
ApplicationData.Current.LocalSettings.Values["user.gender"] = user.Gender;
ApplicationData.Current.LocalSettings.Values["user.location.name"] = user.Location.Name;
ApplicationData.Current.LocalSettings.Values["user.location.name_cn"] = user.Location.NameCn;

Of course, calling ApplicationData.Current.LocalSettings.CreateContainer take a Container can also be stored. (Or better to say a little)

This store, you can update as needed, can also be loaded on demand, for example, I just need it to load only the name of the user name better.

But this program many shortcomings, if one is above Gender is an enumeration, that this code on the bombing. ApplicationData Settings can not be stored directly enumerated type, you need to deal with it (usually transfer values ​​are stored, is not recommended to String deposit). If the field more, then another, followed a few lines of code increases, it is easy to get wrong. But in fact if the field less, then this program is quite appropriate.

Scheme B, the sequence of storage:

ApplicationData.Current.LocalSettings.Values["user"] = JsonConvert.SerializeObject(user);

Speaking of serialization, that is certainly the first time the thought of JSON. This program addresses the pain points A program, but loaded on demand, on-demand update can not be achieved. This program wins in the pan with, including Windows Community Toolkit is to do so. But in my opinion, this program is only to meet the demand, but not good enough. One is dependent on the JSON.net (or other JSON library), the other is a serialization and de-serialization of performance, especially when large objects.

summary:

This is just taking into account the stored user such a structure above, if the structure that is rss, if stored, A program can not almost do, B do program touches. But if make a query (such as queries within a time frame of one day), ApplicationData Settings program can not be solved (Of course, you say that all loaded into memory and then query can do, but just loaded with all EF and then paged out as funny) .

Sqlite program

Sqlite program can in fact be broken down two, one is a direct line and sql, the other is the use ef core of this framework orm. This line and program sql be honest I have not practiced, it is not quite as awesome, I myself have not written a line of sql for many years (although I usually go to work is doing the back-end work). Here mainly to talk about ef core of the program.

Create a new .net standard items:

Snipaste_2020-01-20_11-07-07

Article.cs as follows:

public  class Article
{
    public int Id { get; set; }

    public string Title { get; set; }

    public string Content { get; set; }

    public DateTime PublishTime { get; set; }
}

ApplicationDbContext.cs as follows:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext()
    {
    }

    public DbSet<Article> Articles { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);

        optionsBuilder.UseSqlite("Data Source=articles.db");
    }
}

And project references Microsoft.EntityFrameworkCore.Sqlite package, note the use of version 2.2.6, 3.x with the UWP will be fried!

Then create a database migration:

Snipaste_2020-01-20_11-07-07

Next UWP project references the .net standard library, modify App.xaml.cs code:

public App()
{
    using (var context = new ApplicationDbContext())
    {
        context.Database.Migrate();
    }

    this.InitializeComponent();
    this.Suspending += OnSuspending;
}

When this program will start to perform database migration, the next program code can be used.

Because the theme is not Sqlite, here I am just in a demo level of the attitude of code here as example, but the garden also has a large cattle who have written a more detailed blog post.

summary:

Sqlite program seems very good, but I think there are disadvantages. The program is too heavy a relational database means that data table, like I just want to keep a user's information, then, come on, it can be a little easy? Another is ef core of support UWP, the above I also said, 3.x that will blow up. PS one, Microsoft is not currently UWP got the idea, System.Text.Json this package, version 4.7.0 on the UWP use have to write rd.xml, but 4.6.0 does not need. It concluded that, Sqlite program is to chopper, and we are to kill a chicken.

analysis:

There is no program that ranged between ApplicationData Settings and Sqlite it? Sqlite is a relational database, ah, mean sql. Speaking sql, I think nosql, think MongoDb, Redis these gadgets. In fact, since these are nosql database schema less, that is, there is no table structure, add or delete fields, said there would be no changes to the structure of the table say, is therefore quite suitable for storing them for use in a number of non-critical data. But MongoDb, Redis of these things are needed to end a server, but it certainly can not take a server UWP, then there is no similar Sqlite no such single file server, and UWP use it, then it is of course best with .net development. I find a bit, I found it to be really, the next step is the protagonist of this article - LiteDB.

text:

LiteDB official home page: https://www.litedb.org/

Github:https://github.com/mbdavid/LiteDB

Add in our UWP project LiteDB references . (Note that as used herein, version 5.0.0-rc, because the need to use the corresponding LiteDB Studio below)

To insert the data, for example:

var dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "MyArticles.db");
using (var db = new LiteDatabase(dbPath))
{
    var articles = db.GetCollection<Article>();
    
    was article = new Article
    {
        Title = "test title",
        Content = "test content",
        PublishTime = DateTime.Now
    };

    articles.Insert(article);
}

Database path needs to set about, on the UWP user data folder. Otherwise it will put Appx folder, this path is no written permission.

db.GetCollection <Article> () this sentence is equivalent to creating a document (if not present) in the database, with the concept of Sqlite it is to create a table. Name is called Article, of course, the name can be set by overriding the method. Id We do not need to be set, this is the same with EF, the default is automatically incremented. Then we see if our data into success. Download LiteDB Studio (I downloaded the 0.9 version):

https://github.com/mbdavid/LiteDB.Studio/releases

After downloading open our database, the database path can make a break point to get the value dbPath to the above code.

Open, then look like this:

Snipaste_2020-01-20_13-26-07

Right then we select Query Article

Snipaste_2020-01-20_13-27-08

You can see there have been similar to what we are familiar with the sql statement, then click on the Run button.

Snipaste_2020-01-20_13-28-01

This shows that we just inserted into the data appeared.

 

Back to the demand side, we assume this Article class one day more fields, such as author of the article. Modify Article.cs:

public  class Article
{
    public int Id { get; set; }

    public string Title { get; set; }

    public string Content { get; set; }

    public string Owner { get; set; }

    public DateTime PublishTime { get; set; }
}

修改我们的插入数据代码:

var dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "MyArticles.db");
using (var db = new LiteDatabase(dbPath))
{
    var articles = db.GetCollection<Article>();
    
    var article = new Article
    {
        Title = "test title",
        Content = "test content",
        Owner = "Justin Liu",
        PublishTime = DateTime.Now
    };

    articles.Insert(article);
}

再次看看我们的 LiteDB Studio。

Snipaste_2020-01-20_13-47-48

可见数据是已经插入进去了,没有任何的数据库表迁移,相当优雅而且 easy。

 

要做查询的话也简单:

var dbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "MyArticles.db");
using (var db = new LiteDatabase(dbPath))
{
    var articles = db.GetCollection<Article>();

    var list = articles
        .Find(temp => temp.PublishTime >= DateTime.Parse("2020-01-20 13:00:00"))
        .ToList();
}

Snipaste_2020-01-20_13-54-06

当然还有更多用法,这里就不再介绍了,各位看官可以去看 LiteDB 官方的文档,而且这玩意我觉得算是个较为成熟的东西了。

 

总结:

本文我觉得更偏向于与各位看官交流经验吧,本文中 ApplicationData Settings 的 A、B 方案其实我项目也都有在使用。特别 A 方案,加载数据的时候需要特别严谨的逻辑,例如其中一个字段没有值该如何处理这种。B 方案则简单 catch 个 JsonSerializationException 一般就没问题了,有时候偷个懒还是挺方便的。而 Sqlite 的方案,说句实话,我目前并没有在项目中用到(之前有一个但后来弃坑了,而且是 DbFirst 而不是本文 CodeFirst 的方式)。所以 Sqlite 方案,我在写本文的时候才发现最新的 3.1.1(理论上 3.x 的都这样)在 UWP 上压根就用不了。

For the protagonist of this article, LiteDB. I am optimistic (although I have not used in my project, the next project to find a way to spend ^ - ^). In general, the importance of client data storage is certainly not high, it is important to keep the server are certainly gone. That is, data is more often a client of the cache has played the same role. For example above, if the user no data, that allows users to reauthorize just once, it's nothing. For these scenarios, the relational database is too heavy, and database migration is likely to lose data (this ef create a migration when prompted, but in fact the code definitely going to pay attention). In the service side, if a line missing data fields, then connect to the database manually make up just fine. But if this is the database on the client machine, it is a big head. LiteDB nosql with this database, because there is no migration, so there is no problem of data loss.

One final remark, this article only provides a guideline, but will depend on the actual scene to analyze. Anyway, whether black or white, it catches mice is a good cat thing.

Guess you like

Origin www.cnblogs.com/h82258652/p/12217910.html
UWP