記錄一下通過 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<Entry>().ToTable("Entry"); builder.Entity<Entry>() .Property(e => e.EntryTypeId) .HasColumnName("EntryTypeId"); builder.Entity<EntryType>().ToTable("EntryType"); builder.Entity<EntryTag>().ToTable("EntryTagTable"); builder.Entity<EntryTag>() .Property(t => t.Name) .HasColumnName("TagName"); base.OnModelCreating(builder); Database.SetInitializer(new SqliteDropCreateDatabaseWhenModelChanges<EntryContext>(builder)); } public DbSet<Entry> Entry { get; set; } public DbSet<EntryType> EntryType { get; set; } public DbSet<EntryTag> EntryTag { get; set; } }
}
這里比較重要的是重寫了 OnModelCreating() 方法,這個方法里面通過 fluent api的方式定義了實體類的屬性和具體的數據庫的字段的映射的關系;同時,在默認的構造函數里面,調用基類的構造函數,因為使用sqlite這個數據庫,所以將繼承了DbConnection的實例: new SQLiteConnection("[連接字符串]")
傳遞給基類的構造函數,用來連接數據庫.
</div>