SQLite 的 CodeFirst 模式

来源:https://www.cnblogs.com/hippieZhou/archive/2018/08/04/9420432.html
-Advertisement-
Play Games

[TOC] 目前 EF 是 .NET 平臺下相當成熟的 ORM 框架,但是其最新發佈的 6.x 版本依然不支持 SQLite 的 CodeFirst 模式,好在有大神已經在 Nuget 上發佈的相應的 Package 來解決這個問題。筆者通過做一個小實驗來驗證一下。 問題描述 SQLite 本身不支 ...


目錄


目前 EF 是 .NET 平臺下相當成熟的 ORM 框架,但是其最新發佈的 6.x 版本依然不支持 SQLite 的 CodeFirst 模式,好在有大神已經在 Nuget 上發佈的相應的 Package 來解決這個問題。筆者通過做一個小實驗來驗證一下。

問題描述

SQLite 本身不支持 CodeFirst 模式,當我們的數據模型因業務變化而需要修改的話,那對應的資料庫表也要進行更改。這個時候,如果我們手動修改數據表的話就不太方便,因此我們需要想辦法讓其支持 CodeFirst 模式。筆者通過使用 SQLite.CodeFirst 來嘗試解決上述問題。

解決方案

安裝依賴包

首先我們創建一個控制台程式,安裝如下 Package:

  • System.Data.SQLite
  • SQLite.CodeFirst

修改程式配置 App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>

  <!--新增結點-->
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite.EF6" />
      <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
    <remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
  </system.data>
  
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    
    <!--新增結點-->
    <providers>
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
    
  </entityFramework>

  <!--新增結點-->
  <connectionStrings>
    <add name="sampledb" connectionString="data source=.\sampledb.db" providerName="System.Data.SQLite" />
  </connectionStrings>
  
</configuration>

創建模型對象 Person.cs

[Table("person")]
public class Person
{
    [Column("id"), Key, Autoincrement]
    public int Id { get; set; }
    [Column("firstname")]
    public string FirstName { get; set; }
    [Column("lastname")]
    public string LastName { get; set; }
}

創建數據上下文 PersonDbContext.cs

public class PersonDbContext : DbContext
{
    public DbSet<Person> People { get; set; }

    /// <summary>
    /// 從配置文件讀取鏈接字元串
    /// </summary>
    public PersonDbContext() :
        base("name = sampledb")
    {
        ConfigurationFunc();
    }

    /// <summary>
    /// 代碼指定資料庫連接
    /// </summary>
    /// <param name="existingConnection"></param>
    /// <param name="contextOwnsConnection"></param>
    public PersonDbContext(DbConnection existingConnection, bool contextOwnsConnection) :
        base(existingConnection, contextOwnsConnection)
    {
        ConfigurationFunc();
    }

    private void ConfigurationFunc()
    {
        Configuration.LazyLoadingEnabled = true;
        Configuration.ProxyCreationEnabled = true;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        var initializer = new SqliteDropCreateDatabaseWhenModelChanges<PersonDbContext>(modelBuilder);
        Database.SetInitializer(initializer);
    }
}

此時,當我們修改數據模型時,不需要執行任何 migration 操作就可以將 數據表映射到新的模型上。下麵我們在主程式中調用一下:

主程式調用 Program.cs

class Program
{
    static void Main(string[] args)
    {
        var ptah = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sampledb.db");
        var connection = SQLiteProviderFactory.Instance.CreateConnection();
        connection.ConnectionString = $"Data Source={ptah}";

        //using (var context = new PersonDbContext())
        using (var context = new PersonDbContext(connection, false))
        {
            #region 預熱:針對數據表較多的情況下建議執行下述操作

            var objectContext = ((IObjectContextAdapter)context).ObjectContext;
            var mappingColection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
            mappingColection.GenerateViews(new List<EdmSchemaError>());

            #endregion

            #region 插入數據

            Console.WriteLine("插入數據:");
            context.People.Add(new Person { FirstName = "hippie", LastName = "zhou" });
            context.SaveChanges();

            #endregion

            #region 查找數據

            Console.WriteLine("查找數據:");
            foreach (var people in context.People)
            {
                Console.WriteLine($"{people.Id} - {people.FirstName} - {people.LastName}");
            }

            #endregion

            #region 更改數據

            Console.WriteLine("更改數據:");
            Person person = context.People.Where(p => p.Id == 1)?.FirstOrDefault();
            person.LastName = "Puth";
            context.SaveChanges();

            #endregion

            #region 刪除數據

            Console.WriteLine("刪除數據:");
            Person person = context.People.Where(p => p.Id == 1)?.FirstOrDefault();
            context.People.Remove(person);
            context.SaveChanges();

            #endregion

            Console.ReadKey();
        }
    }
}

註意事項

由於 SQLite.CodeFirst 的 Package 需要依賴 EntityFramework,以及為了能保證數據操作支持相關 LINQ 操作,在上述兩個 Pacakge 安裝的過程中,會同時安裝其它依賴包,所以最終的項目依賴包如下所示:

  • EntityFramework
  • SQLite.CodeFirst
  • System.Data.SQLite
  • System.Data.SQLite.Core
  • System.Data.SQLite.EF6
  • System.Data.SQLite.Linq

此外,需要註意一下 System.Data.SQLiteSystem.Data.SQLite.Core 的區別:

System.Data.SQLite:The official SQLite database engine for both x86 and x64 along with the ADO.NET provider. This package includes support for LINQ and Entity Framework 6.

System.Data.SQLite.Core:The official SQLite database engine for both x86 and x64 along with the ADO.NET provider.

所以,為了能讓 SQLite 支持 CodeFirst ,還是一件挺曲折的事情啊。

相關參考


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • `目錄 start` "Gradle" "書籍" "發行版本列表" "安裝配置" "SDKMAN方式" "Chocolate" "命令行選項" "守護進程" "Docker安裝" "配置鏡像源" "關鍵配置文件" "build.gradle" "初始化一個新項目" "dependency" "統一依 ...
  • c/c++ 用克魯斯卡爾(kruskal)演算法構造最小生成樹 最小生成樹(Minimum Cost Spanning Tree)的概念: 假設要在n個城市之間建立公路,則連通n個城市只需要n 1條線路。這時,自然會考慮,如何在最節省經費的前提下建立這個公路網路。 每2個城市之間都可以設置一條公路,相 ...
  • ThinkPHP 提供了一個 Model 類,供其他的 Model 進行繼承。Model 類中是 MVC 中的模型類,它是調用 持久層 的上層類。感覺這麼描述問題很多,但是有什麼辦法呢?但是,這個 Model 有時無法滿足我們的一些需求,因此我們需要自定義一個 Model 類出來,不過自定義的 Mo ...
  • 開啟idea的tomcat 遠程調試,需要connect 1099埠,也就是開啟JMX功能。 我是centos yum功能重度依賴者,所以tomcat 肯定也是yum 安裝,但預設沒有開啟這個埠。 於是需要開啟這個埠,網上的教程千篇一律,要求添加以下修改 catalina.sh 。然後在通過 ...
  • 異常1: can not run elasticsearch as root 異常1解決方式: 在es-linux環境中,不允許使用root用戶運行ElasticSearch,所以添加一個新的普通用戶就可以了(linux命令如下) 異常2: failed to obtain lock on ... ...
  • 用List實現集合的增刪改查 ...
  • 1. 學習計劃 第十一天: 1、sso註冊功能實現 2、sso登錄功能實現 3、通過token獲得用戶信息 4、Ajax跨域請求(jsonp) 2. Sso系統工程搭建 需要創建一個sso服務工程,可以參考e3-manager創建。 e3-sso(pom聚合工程) |--e3-sso-interfa ...
  • 一、三元表達式 三元表達式僅應用於: 1、條件成立返回一個值 2、條件不成立返回一個值 res=x if x > y else y print(res) 二、函數遞歸 定義:函數的遞歸調用,即在函數調用的過程中,又直接或間接地調用了函數本身 1、直接調用 2、間接調用 遞歸分為兩個階段 1、回溯: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...