通過EntityFramework操作sqlite(DbFirst)


記錄一下通過 EntityFramework6 來操作sqlite過程
環境:

  • visual studio 2017
  • .net 4.5
  • Console Application(項目類型)
  • sqlite3
  • navicat for sqlite

設計數據庫

我使用了 navicat for sqlite 這個圖形界面工具來快速生成數據庫的;
非常簡單,打開 navicat ,按照下圖操作即可

新建表:
Entry表(Id為主鍵,勾選自增),Type_Id為外鍵.

EntryType表(Id為主鍵,勾選自增)

完事之后點擊左上角的保存!

在visual studio中建立控制台項目,安裝必要的nuget包

打開nuget包管理工具,
在Browse選項卡中搜索 System.Data.SQLite
安裝相應的nuget包,如圖所示

之后在nuget包管理工具中查看已安裝的nuget包
如下圖:

然后在解決方案瀏覽器下可以看到App.config文件,

進去修改一下內容,在 provider 節點下加入下面的內容:
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />

建立 Entity 實體類

Entry 類 :

Entry
namespace MagicMemory.Core.Entities
{
    public class Entry
    {
        public int Id { get; set; }
        public string Key { get; set; }
        public string Content { get; set; }
        public int? EntryTypeId { get; set; }
        public virtual EntryType Type { get; set; }
    }
}


這里值得注意的是,Entry實體中有一個外鍵屬性:

public virtual EntryType Type { get; set; }

一定要用virtual來修飾,這里不清楚為啥,我也是偶然看見的,不用virual就沒用,可能因為是Dbfirst的原因,之前在.net core結合efcore使用的時候並不需要加virtual也行.這里的外鍵屬性,Ef 會自動從數據庫里相應的表中給我們映射過來.但是這個外鍵所在表也必須在 DbContext中作為DbSet<>的泛型參數存在才可以.

EntryType 類:

EntryType
using System;

namespace MagicMemory.Core.Entities
{
public class EntryType
{
public int Id { get; set; }
public string Name { get; set; }
}
}

實體類就這兩個,差不多可以說明問題了,建立實體類的時候,實體類的屬性名一定要和表的字段名相匹配(必須一樣才行),名稱不一樣的話,則需要在屬性的上方加一個注解屬性 Column("Name").也可以使用fluentApi來進行配置,我跟喜歡這種方式,在DbContext中重寫OnModelCreating()方法,對 column 進行配置.

當實體類型的屬性名需要和不同名稱的的表中的列進行映射時,可以使用下面的方法.

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(b => b.BlogId)
            .HasColumnName("blog_id");
    }

繼承DbContext,建立數據庫上下文 xxxContext 類

EntryContext
using System.Data.Entity;
using System.Data.SQLite;
using MagicMemory.Core.Entities;
using SQLite.CodeFirst;

namespace MagicMemory.DbStudy
{
public class EntryContext:DbContext
{
public EntryContext():base(new SQLiteConnection("Data Source=MagicMemory.Db"),true)
{
}

    protected override void OnModelCreating(DbModelBuilder builder)
    {
        builder.Entity&lt;Entry&gt;().ToTable(&quot;Entry&quot;);
        builder.Entity&lt;Entry&gt;()
            .Property(e =&gt; e.EntryTypeId)
            .HasColumnName(&quot;EntryTypeId&quot;);

        builder.Entity&lt;EntryType&gt;().ToTable(&quot;EntryType&quot;);

        builder.Entity&lt;EntryTag&gt;().ToTable(&quot;EntryTagTable&quot;);
        builder.Entity&lt;EntryTag&gt;()
            .Property(t =&gt; t.Name)
            .HasColumnName(&quot;TagName&quot;);

        base.OnModelCreating(builder);

        Database.SetInitializer(new SqliteDropCreateDatabaseWhenModelChanges&lt;EntryContext&gt;(builder));
    }

    public DbSet&lt;Entry&gt; Entry { get; set; }
    public DbSet&lt;EntryType&gt; EntryType { get; set; }
    public DbSet&lt;EntryTag&gt; EntryTag { get; set; }
}

}

這里比較重要的是重寫了 OnModelCreating() 方法,這個方法里面通過 fluent api的方式定義了實體類的屬性和具體的數據庫的字段的映射的關系;同時,在默認的構造函數里面,調用基類的構造函數,因為使用sqlite這個數據庫,所以將繼承了DbConnection的實例: new SQLiteConnection("[連接字符串]") 傳遞給基類的構造函數,用來連接數據庫.

  </div>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM