选择SQLite的理由

在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的:

1,微软做的UWP应用大部分也是用Sqlite。或者说是微软推荐使用Sqlite吧!

2,简单!就只有一个类库没有多余的参照什么的。不像其他数据库还得做复杂配置什么的麻烦!

3,不需要数据库服务,数据服务和客户都在同一个进程里面。如下图:

4,作为存储系统它只支持一个用户一个数据实体。

5,跨平台跨结构,这个好!

Sqlite主要使用内容

如果想充分使用好Sqlite数据库,建议保存好下面两个链接

  • The database connection handle
  • The prepared statement object
    操作上面对象主要的6个接口
  • sqlite3_open()
  • sqlite3_prepare()
  • sqlite3_step()
  • sqlite3_column()
  • sqlite3_finalize()
  • sqlite3_close()

    SQLite数据持久层:Entity Framework Core

    随着Entity Framework开源在.Net开发中越来越受欢迎,包括WinFrom,Asp.net MVC开发等等。为了跨平台在6.0后就是Entity Framwork Core版本。开源地址:https://github.com/aspnet/EntityFramework

    使用Entity Framwork Core当然得有个驱动才能调用SQLite数据库,那就是SQLite的ADO.NET驱动。大概层次如下:

    ORM具体实现

    此处做一个显示课程列表信息的UWP做实例。源代码:https://github.com/NewBLife/UWP/tree/master/SqliteEFCoreDemo

    1,新建一个空的UWP项目叫SqliteEFCoreDemo。

    2,添加包引用。

    Install-Package EntityFramework.SQLite –Pre

    Install-Package EntityFramework.Commands –Pre

    3,创建Student和Course的Entity。

    // ***********************************************************************
    // FileName:Course
    // Description:
    // Project:
    // Author:NewBLife
    // Created:2016/5/28 21:25:32
    // Copyright (c) 2016 NewBLife,All rights reserved.
    // *********************************************************************** using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema; namespace SqliteEFCoreDemo.Models
    {
    /// <summary>
    /// 设置数据库表名
    /// </summary>
    [Table(name: "Course")]
    public class Course
    {
    /// <summary>
    /// ID不为空设置为Required
    /// </summary>
    [Required]
    public string ID { get; set; }
    public string Name { get; set; }
    }
    }
    // ***********************************************************************
    // FileName:Student
    // Description:
    // Project:
    // Author:NewBLife
    // Created:2016/5/28 21:23:45
    // Copyright (c) 2016 NewBLife,All rights reserved.
    // ***********************************************************************
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema; namespace SqliteEFCoreDemo.Models
    {
    /// <summary>
    /// 设置数据库表名
    /// </summary>
    [Table(name: "Student")]
    public class Student
    {
    /// <summary>
    /// ID不为空设置为Required
    /// </summary>
    [Required]
    public string ID { get; set; } public string Name { get; set; } public List<Course> Courses { get; set; }
    }
    }

    4,创建数据库操作EfDbContext继承于Microsoft.Data.Entity.DbContext。

    // ***********************************************************************
    // FileName:EfDbContext
    // Description:
    // Project:
    // Author:NewBLife
    // Created:2016/5/28 21:32:23
    // Copyright (c) 2016 NewBLife,All rights reserved.
    // ***********************************************************************
    using Microsoft.Data.Entity; namespace SqliteEFCoreDemo.Models
    {
    public class EfDbContext : DbContext
    {
    /// <summary>
    /// 注意:如果Student的Model里面没有设置表名将使用Students作为表名
    /// </summary>
    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
    // 配置数据库名
    optionsBuilder.UseSqlite("Filename=School.db");
            }
    }
    }

    5,编译项目(非常重要,不然有可能后续步骤出错)。

    6,高级操作:创建差分文件Migration。通过查看差分文件可以判断生成的表结构或者数据是不是正确(这是Entity Framework进行CodeFirst开发的便捷之处)。

    在程序包管理器中执行:add-migration initDb。将自动创建下图红色部分内容(这就是Entity Framework强大之处)。

    自动生成的表结构代码如下:

    using System;
    using Microsoft.Data.Entity;
    using Microsoft.Data.Entity.Infrastructure;
    using Microsoft.Data.Entity.Metadata;
    using Microsoft.Data.Entity.Migrations;
    using SqliteEFCoreDemo.Models; namespace SqliteEFCoreDemo.Migrations
    {
    [DbContext(typeof(EfDbContext))]
    partial class EfDbContextModelSnapshot : ModelSnapshot
    {
    protected override void BuildModel(ModelBuilder modelBuilder)
    {
    modelBuilder
    .HasAnnotation("ProductVersion", "7.0.0-rc1-16348"); modelBuilder.Entity("SqliteEFCoreDemo.Models.Course", b =>
    {
    b.Property<string>("ID"); b.Property<string>("Name"); b.Property<string>("StudentID"); b.HasKey("ID"); b.HasAnnotation("Relational:TableName", "Course");
    }); modelBuilder.Entity("SqliteEFCoreDemo.Models.Student", b =>
    {
    b.Property<string>("ID"); b.Property<string>("Name"); b.HasKey("ID"); b.HasAnnotation("Relational:TableName", "Student");
    }); modelBuilder.Entity("SqliteEFCoreDemo.Models.Course", b =>
    {
    b.HasOne("SqliteEFCoreDemo.Models.Student")
    .WithMany()
    .HasForeignKey("StudentID");
    });
    }
    }
    }

    自动生成的数据更新代码如下:

    using System;
    using System.Collections.Generic;
    using Microsoft.Data.Entity.Migrations; namespace SqliteEFCoreDemo.Migrations
    {
    public partial class initDb : Migration
    {
    protected override void Up(MigrationBuilder migrationBuilder)
    {
    migrationBuilder.CreateTable(
    name: "Student",
    columns: table => new
    {
    ID = table.Column<string>(nullable: false),
    Name = table.Column<string>(nullable: true)
    },
    constraints: table =>
    {
    table.PrimaryKey("PK_Student", x => x.ID);
    });
    migrationBuilder.CreateTable(
    name: "Course",
    columns: table => new
    {
    ID = table.Column<string>(nullable: false),
    Name = table.Column<string>(nullable: true),
    StudentID = table.Column<string>(nullable: true)
    },
    constraints: table =>
    {
    table.PrimaryKey("PK_Course", x => x.ID);
    table.ForeignKey(
    name: "FK_Course_Student_StudentID",
    column: x => x.StudentID,
    principalTable: "Student",
    principalColumn: "ID",
    onDelete: ReferentialAction.Restrict);
    });
    } protected override void Down(MigrationBuilder migrationBuilder)
    {
    migrationBuilder.DropTable("Course");
    migrationBuilder.DropTable("Student");
    }
    }
    }

    每次执行Add-Migration 名称 都会根据你的Model修改创建差分的Migration文件。

    7,重量级操作:在App.xaml.cs的构造方法中添加如下代码来生成真正的数据库文件。

    public App()
    {
    this.InitializeComponent();
    this.Suspending += OnSuspending; using (var db = new EfDbContext())
    {
    // 将差分文件写入数据库文件
    db.Database.Migrate();
    }
    }

    8,添加演示布局以及Model的绑定设置。

    <Page
    x:Class="SqliteEFCoreDemo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SqliteEFCoreDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:data="using:SqliteEFCoreDemo.Models"
    mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <RelativePanel HorizontalAlignment="Center" Margin="0,50,0,0">
    <Grid Name="Header" Width="">
    <Grid.RowDefinitions>
    <RowDefinition Height=""/>
    <RowDefinition Height=""/>
    <RowDefinition Height=""/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width=""/>
    <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <TextBlock Name="lblCID"
    Grid.Column=""
    Grid.Row=""
    Text="课程ID:"/>
    <TextBox Name="txbCId"
    Grid.Column=""
    Grid.Row=""
    Width=""/>
    <TextBlock Name="lblCName"
    Grid.Column=""
    Grid.Row=""
    Text="课程名称:"/>
    <TextBox Name="txbCName"
    Width=""
    Grid.Column=""
    Grid.Row="" />
    <Button Name="btnAdd"
    Grid.Column=""
    Grid.Row=""
    Width=""
    Click="btnAdd_Click"
    Content="Add Course"/>
    </Grid>
    <Grid Name="List"
    RelativePanel.Below="Header">
    <ListView Name="lstCourse">
    <ListView.ItemTemplate>
    <DataTemplate x:DataType="data:Course">
    <Grid>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width=""/>
    <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="" Text="{x:Bind ID,Mode=OneWay}"/>
    <TextBlock Grid.Column="" Text="{x:Bind Name,Mode=OneWay}"/>
    </Grid>
    </DataTemplate>
    </ListView.ItemTemplate>
    </ListView>
    </Grid>
    </RelativePanel>
    </Grid>
    </Page>
    using System.Linq;
    using SqliteEFCoreDemo.Models;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls; //“空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 上有介绍 namespace SqliteEFCoreDemo
    {
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page
    {
    public MainPage()
    {
    this.InitializeComponent();
    this.Loaded += MainPage_Loaded;
    } private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
    using (var db = new EfDbContext())
    {
    lstCourse.ItemsSource = db.Courses.ToList();
    }
    } private void btnAdd_Click(object sender, RoutedEventArgs e)
    {
    using (var db = new EfDbContext())
    {
    var newCourse = new Course
    {
    ID = txbCId.Text.Trim(),
    Name = txbCName.Text.Trim()
    }; txbCId.Text = string.Empty;
    txbCName.Text = string.Empty; db.Courses.Add(newCourse);
    db.SaveChanges(); lstCourse.ItemsSource = db.Courses.ToList();
    }
    }
    }
    }

    9,启动应用,添加数据试试。

    10,查看自动创建的数据库文件。

    Not Null设置,外键设置等等都自动设置好了!好强大有没有…

    总结

    用EFCore做数据库持久层只需要面向对象模型做处理就可以,与数据模型的交互等交给Entity Framework Core处理。总的来说使用很方便,节省不少工作量。

UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?的更多相关文章

  1. UWP开发之Template10实践二:拍照功能你合理使用了吗?(TempState临时目录问题)

    最近在忙Asp.Net MVC开发一直没空更新UWP这块,不过有时间的话还是需要将自己的经验和大家分享下,以求共同进步. 在上章[UWP开发之Template10实践:本地文件与照相机文件操作的MVV ...

  2. UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)

    前面[UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理]章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例. 原代码地址:ht ...

  3. UWP开发之Mvvmlight实践七:如何查找设备(Mobile模拟器、实体手机、PC)中应用的Log等文件

    在开发中或者后期测试乃至最后交付使用的时候,如果应用出问题了我们一般的做法就是查看Log文件.上章也提到了查看Log文件,这章重点讲解下如何查看Log文件?如何找到我们需要的Packages安装包目录 ...

  4. UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享

    在前几章介绍了不少MVVM以及Mvvmlight实例,那实际企业开发中将以那种架构开发比较好?怎样分层开发才能节省成本? 本文特别分享实际企业项目开发中使用过的项目架构,欢迎参照使用!有不好的地方欢迎 ...

  5. UWP: 在 UWP 中使用 Entity Framework Core 操作 SQLite 数据库

    在应用中使用 SQLite 数据库来存储数据是相当常见的.在 UWP 平台中要使用 SQLite,一般会使用 SQLite for Universal Windows Platform 和 SQLit ...

  6. UWP开发之Mvvmlight实践二:Mvvmlight的核心框架MVVM与MVC、MVP的区别(图文详解)

    最近UWP开发在海外很潮流,随着微软收购Xamarin,我们这些C#程序员也可以靠这杆小米枪挑战Android,IOS平台了. 那我们为什么选择MVVM做UWP开发?MVC,MVP,MVVM他们之间到 ...

  7. UWP开发之Mvvmlight实践八:为什么事件注销处理要写在OnNavigatingFrom中

    前一段开发UWP应用的时候因为系统返回按钮事件(SystemNavigationManager.GetForCurrentView().BackRequested)浪费了不少时间.现象就是在手机版的详 ...

  8. UWP开发之Mvvmlight实践六:MissingMetadataException解决办法(.Net Native下Default.rd.xml配置问题)

    最近完成一款UWP应用,在手机端测试发布版(Release)的时候应用莫名奇妙的强行关闭,而同样的应用包在PC端一点问题都没有,而且Debug版在两个平台都没有问题,唯独手机的Release版有问题. ...

  9. UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理

    最近比较忙有一段时间没有更新了,再接再厉继续分享. 案例下载:https://github.com/NewBLife/UWP/tree/master/SuspendSample 先我们看看App在生命 ...

随机推荐

  1. 谈一下关于CQRS架构如何实现高性能

    CQRS架构简介 前不久,看到博客园一位园友写了一篇文章,其中的观点是,要想高性能,需要尽量:避开网络开销(IO),避开海量数据,避开资源争夺.对于这3点,我觉得很有道理.所以也想谈一下,CQRS架构 ...

  2. JavaScript中fn()和return fn()

    看博客时,注意到return的重要性 参考:http://www.cnblogs.com/raoyunxiao/p/5644032.html 看似反常的例子: var i = 0; function ...

  3. .NET Core采用的全新配置系统[10]: 配置的同步机制是如何实现的?

    配置的同步涉及到两个方面:第一,对原始的配置文件实施监控并在其发生变化之后从新加载配置:第二,配置重新加载之后及时通知应用程序进而使后者能够使用最新的配置.要了解配置同步机制的实现原理,先得从认识一个 ...

  4. JS图片上传预览插件制作(兼容到IE6)

    其实,图片预览功能非常地常见.很意外,之前遇到上传图片的时候都不需要预览,也一直没有去实现过.现在手上的项目又需要有图片预览功能,所以就动手做了一个小插件.在此分享一下思路. 一.实现图片预览的一些方 ...

  5. spring boot 实战:我们的第一款开源软件

    在信息爆炸时代,如何避免持续性信息过剩,使自己变得专注而不是被纷繁的信息所累?每天会看到各种各样的新闻,各种新潮的技术层出不穷,如何筛选出自己所关心的? 各位看官会想,我们是来看开源软件的,你给我扯什 ...

  6. 微信小程序开发日记——高仿知乎日报(下)

    本人对知乎日报是情有独钟,看我的博客和github就知道了,写了几个不同技术类型的知乎日报APP 要做微信小程序首先要对html,css,js有一定的基础,还有对微信小程序的API也要非常熟悉 我将该 ...

  7. 我的第一个python程序--给2.x的print代码加上括号

    最近想学习一门脚本语言,综合考虑,选择了python. 花了几天时间看完了 简明 Python 教程 ,想着应该写点什么东西才好,刚好我使用的是3.x版本,以前好多2.x的代码都直接报错,尤其是pri ...

  8. ASP.NET MVC Model验证(一)

    ASP.NET MVC Model验证(一) 前言 前面对于Model绑定部分作了大概的介绍,从这章开始就进入Model验证部分了,这个实际上是一个系列的Model的绑定往往都是伴随着验证的.也会在后 ...

  9. Chrome 控制台不完全指南

    Chrome的开发者工具已经强大到没朋友的地步了,特别是其功能丰富界面友好的console,使用得当可以有如下功效: 更高「逼格」更快「开发调试」更强「进阶级的Frontender」 Bug无处遁形「 ...

  10. ABP(现代ASP.NET样板开发框架)系列之20、ABP展现层——动态生成WebApi

    点这里进入ABP系列文章总目录 ABP(现代ASP.NET样板开发框架)系列之20.ABP展现层——动态生成WebApi ABP是“ASP.NET Boilerplate Project (ASP.N ...