練習Code First
tools:vs2015 sqlServer2012
新建項目
新建-項目-Visual C#-windows-控制臺應用程序,命名為:CodeFirstDemo。
安裝EntityFramework程序包
新建好CodeFirstDemo項目后,我們先來安裝EntityFramework,項目-管理NuGet程序包-聯機-搜索“EntityFramework”,下載安裝。
安裝完成后會在項目下自動添加EntityFramework引用:

在Program.cs下添加命名空間 using System.Data.Entity;
創(chuàng)建模型
為了簡單我們直接在Program.cs中創(chuàng)建模型,以后可分離出去
public class New
{
public int NewId { get; set; }
public string Title { get; set; }
public int NewTypeId { get; set; }
public virtual NewType NewType { get; set; }
}
public class NewType
{
public int NewTypedId { get; set; }
public string Name { get; set; }
public int BlogId { get; set; }
public virtual List<New> New { get; set; }
}
NewId和NewTypeId在創(chuàng)建的時候會做為表的主鍵,因為包含有ID關鍵字,如果不包含的話,需要我們指定主鍵,要不然創(chuàng)建就會報未找到主鍵的錯誤,添加命名空間:
using System.ComponentModel.DataAnnotations;
并在屬性前添加[Key]標注,指示此字段作為主鍵:
[Key]
public int NewId { get; set; }
[Key]
public int NewTypedId { get; set; }
當然除了Key,System.ComponentModel.DataAnnotations命名空間下還有其他的Attribute,這邊就不多說,可以查看msdn有關教程:http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx。
需要注意的另外一點,上面定義模型屬性的時候有virtual關鍵字,表示延遲加載,我的理解是這樣:當我訪問主實體的時候,啟動延遲加載,而不會查詢數據庫的子實體,只有要訪問它的時候才會去數據庫查詢加載,泛型List表示此實體是一對多的關系。
EF默認是啟動延遲加載的,我們如果不需要也可以手動禁止:
db.Configuration.LazyLoadingEnabled = false;
創(chuàng)建上下文DbContext
DBContext,可以理解為是一個容器,里面有對象與數據表的映射關系以及對象本身.
我對EF中上下文的理解:可以把上下文看成一個數據庫控制器,我們可以在其中查詢、更改、刪除數據,然后通過連接獲取或是提交。就像是遙控車的遙控器一樣,EF是這個遙控器的核心部件,天線是連接字符串,遙控車是數據庫,這個比喻可能不是很恰當,但就是這個意思,大家都懂得。
public class NewsContext : DbContext
{
public DbSet<New> News { get; set; }
public DbSet<NewType> NewTypes { get; set; }
}
DbSet表示上下文中給定類型的所有實體的集合或可從數據庫中查詢的給定類型的所有實體的集合,就像是一個包裹,需要什么東西就往里面裝什么東西。
配置連接字符串
vs默認可以生成數據庫,數據庫名是項目命名空間+上下文,有時候我們需要自己定義生成數據庫名稱,或是生成數據庫到指定的服務器,而且有時候數據庫遷移了,我們不能再重新生成一遍吧,這時候我們就要自定義數據庫連接字符串了:
<connectionStrings>
<add name="NewsContext" providerName="System.Data.SqlClient" connectionString="Data Source=(local);Initial Catalog=CodeFirstDemoDB;User ID=sa;Password=sa" />
</connectionStrings>
需要注意的是:連接字符串的名稱必須要和上下文一致,而且connectionStrings必須放在configuration節(jié)點內的最下面
創(chuàng)建數據庫、讀/寫數據
在Program.cs的Main方法中填寫代碼:
using(var db=new NewsContext())
{
Console.Write("輸入新聞類型標題: ");
var name = Console.ReadLine();
var type_Model = new NewType { Name = name };
db.NewTypes.Add(type_Model);
db.SaveChanges();
Console.WriteLine("查詢新聞類型標題: ");
var search_type = Console.ReadLine();
var query = from b in db.NewTypes
where b.Name == search_type
select b;
Console.WriteLine("查詢結果: ");
foreach (var item in query)
{
Console.WriteLine(item.Name);
}
Console.ReadKey();
}
上面代碼創(chuàng)建一個上下文對象實例,通過該實例添加一個新聞實體,然后通過輸入的值,linq查詢結果輸出。

通過上面的操作,我們并沒有創(chuàng)建什么連接字符串和數據庫操作,但是打開數據庫就可以看到我們通過Code First創(chuàng)建的數據庫了。

CodeFirst遷移
關于Code First 遷移其實就是我們在更改模型的時候,數據庫要相應的更改。
- 例如我們上面創(chuàng)建NewTypes表的時候,沒有指定字段的長度,默認是創(chuàng)建字段類型是nvarchar(MAX),有時候我們覺得字段長度太長,需要修改一下字段長度,不要直接去修改數據庫,而是在模型中修改:
[MaxLength(50)]
public string Name { get; set; }
MaxLength就是上面我們說到DataAnnotations命名空間下的類型,這邊我們注意下,我們在生成數據庫的時候添加了一條數據,Name字段值是“2017年大吉”,看看我們修改字段長度后,字段值是否發(fā)生變化?
- 在程序包管理器控制臺輸入
Enable-Migrations命令來啟用遷移,運行完成后在項目中會創(chuàng)建一個Migrations文件夾,下來有兩類文件:

- Configuration.cs — 此文件包含“遷移”將用來遷移 BloggingContext 的設置。在本演練中不需要進行任何更改,但是,在此處可以指定種子數據、為其他數據庫注冊提供程序、更改生成遷移的命名空間等。
- <時間戳>_InitialCreate.cs — 這是第一個遷移,它表示已經應用于數據庫的更改。應用更改的目的是將其從空數據庫遷移至包含博客和文章表的數據庫。盡管我們讓 Code First 自動創(chuàng)建這些表,現在我們選擇“遷移”(已轉化為一次“遷移”)。Code First 還在本地數據庫中記錄:該“遷移”已經應用。文件名中的時間戳用于排序。
需要注意的是:在我們生成數據庫的時候,除了New和NewType表外,還有一個系統(tǒng)生成表__MigrationHistory,從表名上就可以看出是遷移歷史記錄表。
- 在程序包管理器控制臺輸入
Add-Migration Update-NewType-Name命令,Add-Migration表示增加一個遷移,后面是遷移名稱,這個我們可以隨便寫,運行后會自動檢測模型和數據庫發(fā)生的變化,在Migrations文件夾下會生成一個“201702030624087_Update-NewType-Name.cs”文件,打開我們可以看到更新內容
namespace codeFirstDemo.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class UpdateNewTypeName : DbMigration
{
public override void Up()
{
AlterColumn("dbo.NewTypes", "Name", c => c.String(maxLength: 50));
}
public override void Down()
{
AlterColumn("dbo.NewTypes", "Name", c => c.String());
}
}
}
從上面可以看出就是我們上面修改模型的內容,當然你也可以在這上面直接修改,比如你再加一個更新,可以一起提交到數據庫。
- 在程序包管理器控制臺輸入“Update-Database”命令,表示將所有的遷移應用到數據庫,打開數據庫,我們看一下效果:

從上面可以看出,字段Name的類型已經修改為nvarchar(50),而且字段值并沒有發(fā)生變化,可以證明,Code First遷移并不是刪除數據庫再創(chuàng)建。
Code First遷移除了上面說的字段類型修改還有很多內容,比如添加字段,刪除字段,刪除表等等,但都是大同小異,可以舉一反三。
示例Demo下載
本文參照初試Code First(附Demo).