標籤:
1.樣本項目概覽
第一步,添加EntityFramework到項目中,一條命令搞定。開啟Nuget控制台,輸入如下語句:
PM> install-package entityframework
2.建立實體
首先,為各實體公用屬性提取出來放在基類EntityBase中,所有實體繼承自EntityBase。
public class EntityBase { //主鍵Id public int Id { get; set; } /// <summary> /// 建立時間 /// </summary> public DateTime CreateTime { get; set; } public EntityBase() { CreateTime = DateTime.Now; } }
Student實體代碼如下:
public class Student:EntityBase { public string Name { get; set; } public DateTime? Birthday { get; set; } public string Phone { get; set; } public string Email { get; set; } public string Address { get; set; } }
Teacher實體代碼:
public class Teacher:EntityBase { public string Name { get; set; } public string Phone { get; set; } public string Email { get; set; } public string Subject { get; set; } public int StudentCount { get; set; } }
3.實體配置
同樣,為了節省碼量,實體配置也建一個基類MapBase<T>,所有實體配置類(繼承自EntityBase)都繼承基類EntityBase<T>,方便配置。
public class MapBase<T>:EntityTypeConfiguration<T> where T:EntityBase { public MapBase(string tableName=null) { //表名配置 tableName = tableName ?? typeof (T).Name; ToTable(tableName); //關鍵配置(int 自增主鍵) HasKey(m => m.Id) .Property(m => m.Id) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); } }
表名預設為實體為,主鍵為int自增。
Student和Teacher實體的配置:
public class StudentMap:MapBase<Student> { public StudentMap() { //屬性配置 Property(m => m.Name) .HasMaxLength(20) .IsRequired(); Property(m => m.Address) .HasMaxLength(200) .IsRequired(); Property(m => m.Email) .IsUnicode(false) .HasMaxLength(255); Property(m => m.Phone) .IsUnicode(false) .HasMaxLength(11) .IsRequired(); } }
public class TeacherMap:MapBase<Teacher> { public TeacherMap() { Property(m => m.Name) .HasMaxLength(20) .IsRequired(); Property(m => m.Phone) .IsUnicode(false) .IsRequired(); Property(m => m.Email) .IsUnicode(false) .HasMaxLength(255); Property(m => m.Subject) .HasMaxLength(50); } }
繼承了EntityBase之後,主鍵的配置和表名的映射都由基類實現。這裡說一下Fluent配置:IsUnicode(false)表示設定資料庫欄位類型為varchar,string類型的屬性預設映射到資料庫是nvarchar類型,更多Fluent相關的知識園子也很多,不多介紹。
4.EF資料操作上下文
實體配置完後,開始配置DbContext。
public class CodeFirstDbContext:DbContext { /// <summary> /// 資料庫連接配置 /// </summary> public CodeFirstDbContext() :base("name=codeFirstConnectionStr") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { //EF之前的寫法 //modelBuilder.Configurations.Add(new StudentMap()); //modelBuilder.Configurations.Add(new TeacherMap()); //EF6之後的寫法 modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); //載入當前啟動並執行程式集配置 //modelBuilder.Configurations.AddFromAssembly(typeof (MapBase<>).Assembly); //指定程式集載入配置 base.OnModelCreating(modelBuilder); } }
EF6之後簡化了model build,可以直接利用Configurations.AddFromAssembly()載入配置資訊,不用再一一添加。
另外,ctor方法中的name=codeFirstConnectionStr中的codeFirstConnectionStr是資料連線字串的名稱,資料庫連接配置如下:
<connectionStrings> <add name="codeFirstConnectionStr" providerName="System.Data.SqlClient" connectionString="server=.;database=CodeFirst_Demo;uid=sa;pwd=123456"/></connectionStrings>
5.產生資料庫,操作EF上下文
到這裡,所有相關的配置都完成了,接下來就是產生資料庫並做相關操作了。
class Program { static void Main(string[] args) { using (var ctx=new CodeFirstDbContext()) { ctx.Database.CreateIfNotExists(); ctx.Set<Student>().Add(new Student() { Name = "張三", Address = "深圳南山", Birthday =DateTime.Now.AddYears(-20), Email = "[email protected]", Phone = "13888888888" }); ctx.SaveChanges(); } using (var ctx = new CodeFirstDbContext()) { ctx.Set<Teacher>().Add(new Teacher() { Name = "李四", Email = "[email protected]", Phone = "13899999999", Subject = "軟體工程:從入門到住院" }); ctx.SaveChanges(); } Console.Read(); } }
產生之後的資料庫是這樣的:
資料也寫了進去:
5.小結
這個樣本非常簡單,並沒有涵蓋EF的所有相關知識,比如導覽屬性、並發配置、資料移轉等。在實際的項目中,DbContext並不會直接暴露出去,還會用Reponsitory或Service作基礎方法的封裝,又或結合DDD放在基礎設施層。
EntityFramework Code Firse 簡單樣本