第六節:框架搭建之EF的Fluent Api模式的使用流程
一. 前言
沉寂了約一個月的時間,今天用一篇簡單的文章重新迴歸部落格,主要來探討一下Fluent Api模式在實際專案中的使用流程。
1. Fluent API屬於EF CodeFirst模式的一種,EF還有一種模式是DataAnnotations,兩種模式各有千秋吧,前面的EF系列已經詳細介紹過他們的使用了,本節主要介紹 Fluent API模式在實際框架中的使用流程.
2. 框架模式
這裡不採用傳統的三層架構(DAL、BLL),而是使用:Ypf.DTO、Ypf.Service、Ypf.IService、Ypf.Utils、Ypf.Web 這種劃分模式,本節為了方便測試,僅僅使用 Ypf.Service 和 Ypf.Test(控制檯)兩個框架進行測試。
3. 業務模擬
①. 使用者基本資訊和角色基本資訊,不做關聯
②. 使用者資訊增加了或者刪除
③. 角色資訊刪除了或者增加
二. 使用步驟
1. 新建【Ypf.Service】類庫和【Ypf.Test】控制檯專案,並分別通過Nuget安裝EF程式集。
2. 在【Ypf.Service】類庫中新建“UserInfor”、“RoleInfor”實體類,“UserInforConfig”、“RoleInforConfig”實體類對應的隔離出來的表的配置檔案。
PS:這裡為了方便管理,一張表對應一個EF的配置類檔案,比全部直接寫在 OnModelCreating 方法中更清晰。
分享實體類程式碼:
1/// <summary> 2/// 使用者表 3/// </summary> 4public class UserInfor 5{ 6public string id { get; set; } 8public string userName { get; set; } 10public int userAge { get; set; } 11 14} 15/// <summary> 16/// 角色資訊 17/// </summary> 18public class RoleInfor 19{ 20public string id { get; set; } 22public string roleName { get; set; } 24public int roleAge { get; set; } 25}
分享表配置檔案程式碼:
1/// <summary> 2/// UserInfor實體對應表的配置 3/// </summary> 4class UserInforConfig :EntityTypeConfiguration<UserInfor> 5{ 6public UserInforConfig() 7{ 8this.ToTable("T_UserInfor"); 9this.HasKey<string>(u => u.id).Property(u => u.id).HasColumnType("varchar").HasMaxLength(32); 10this.Property(u => u.userName).HasColumnType("varchar").HasMaxLength(50); 11this.Property(u => u.userAge).HasColumnType("int").IsRequired(); 12} 13} 14/// <summary> 15/// RoleInfor實體對應表的配置 16/// </summary> 17class RoleInforConfig : EntityTypeConfiguration<RoleInfor> 18{ 19public RoleInforConfig() 20{ 21this.ToTable("T_RoleInfor"); 22this.HasKey<string>(u => u.id).Property(u => u.id).HasColumnType("varchar").HasMaxLength(32); 23this.Property(u => u.roleName).HasColumnType("varchar").HasMaxLength(50); 24this.Property(u => u.roleAge).HasColumnType("int").IsRequired(); 25} 26}
3. 在【Ypf.Service】類庫中新建EF上下文 “YpfContext”類,使用EF的預設初始化策略( DB不存在則建立,實體不對應則報錯 ) ,然後override OnModelCreating方法,並通過反射一次性載入EF的所有Fluent Api配置,最後宣告要對映的實體。
分享EF上下文的程式碼
public class YpfContext:DbContext { /// <summary> /// 繼承父類建構函式,ypfConnectionString代表配置檔案中連線字串的名字 /// </summary> public YpfContext():base("name=ypfConnectionString") { } /// <summary> /// OnModelCreating方法重寫,FluentAPI對錶的配置都是在該方法中,但是當表數量多的話 /// 該方法內部就會顯得特別亂,所以我們這裡採用分離的方式,一張表對應一個配置檔案類, /// 最後全部註冊到該方法中即可 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //1. 分開註冊 //modelBuilder.Configurations.Add(new UserInforConfig()); //modelBuilder.Configurations.Add(new RoleInforConfig()); //2. 一次性載入所有Fluent API的配置 modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); } public DbSet<UserInfor> UserInfor { get; set; } public DbSet<RoleInfor> RoleInfor { get; set; } }
4. 給【Ypf.Test】配置資料庫連線字串,並且進行一個簡單的資料庫查詢操作,會發現在SQLServer預設目錄生成一個名為“FrameFluentApiDB”的資料庫,且表、欄位對應均正確。
分享資料庫連線字串程式碼:
1<connectionStrings> 2<add name="ypfConnectionString" connectionString="Data Source=localhost;Initial Catalog=FrameFluentApiDB;User ID=sa;Password=123456" providerName="System.Data.SqlClient" /> 3</connectionStrings>
分享簡單的資料庫查詢程式碼:
1class Program 2{ 3static void Main(string[] args) 4{ 5using (YpfContext db=new YpfContext()) 6{ 7var list = db.UserInfor.ToList(); 8 9Console.WriteLine("建立成功"); 10Console.ReadKey(); 11} 12} 13}
執行後生成的資料庫:
5. 給UserInfor實體增加一個“userSex”屬性,並在UserInforConfig檔案中對該屬性進行配置,如下圖,再次執行程式碼,報錯,提示上下文發生改變,請走資料遷移。
修改後程式碼:
報錯提示:
PS:配置資料遷移策略固然可以解決該問題,但我們這裡用一種比較笨的方法,關閉資料庫初始化策略,然後手動配置程式碼和修改資料庫欄位進行對應即可。
分享關閉資料庫初始化策略的程式碼:
手動修改資料庫和程式碼實體中的屬性對應後重新執行程式碼,執行成功。