.ADO.NET Entity Framework 是微軟以 ADO.NET 為基礎(chǔ)所發(fā)展出來的對象關(guān)系對應(yīng) (O/R Mapping) 解決方案,實體框架Entity Framework 是 ADO.NET 中的一組支持開發(fā)面向數(shù)據(jù)的軟件應(yīng)用程序的技術(shù)。是微軟的一個ORM框架。
為什么使用 Code First
開發(fā)新應(yīng)用程序時,數(shù)據(jù)模型會頻繁更改。每當(dāng)模型更改時,模型都無法與數(shù)據(jù)庫保持同步。 你已配置實體框架會自動刪除并重新創(chuàng)建每次更改數(shù)據(jù)模型的數(shù)據(jù)庫。 當(dāng)添加、 刪除或更改實體類或更改你DbContext類,在下次運行應(yīng)用程序時自動刪除您現(xiàn)有的數(shù)據(jù)庫,創(chuàng)建一個新的匹配該模型,并使用測試數(shù)據(jù)為其設(shè)定種子。當(dāng)在生產(chǎn)環(huán)境中運行應(yīng)用程序時,它通常會存儲你想要保留,并且不想丟失所有每次進行一次更改如添加新列的數(shù)據(jù)通過啟用 Code First 來更新數(shù)據(jù)庫架構(gòu)而不是刪除并重新創(chuàng)建數(shù)據(jù)庫安裝 Entity Framework 6
- 從工具菜單中,選擇NuGet 包管理器,然后選擇程序包管理器控制臺。
- 在中程序包管理器控制臺窗口中,輸入以下命令:
Install-Package EntityFramework
- 創(chuàng)建數(shù)據(jù)模型
- 實體創(chuàng)建
public class Student
{
/// <summary>
/// ID 屬性將成為對應(yīng)于此類的數(shù)據(jù)庫表中的主鍵
/// </summary>
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
/// <summary>
/// Gender 是枚舉,問號后Grade類型聲明指示Grade屬性是空
/// 表示一個等級未知或者尚未分配。
/// </summary>
public Gender? Gender{ get; set; }
/// <summary>
/// Enrollments 屬性是導(dǎo)航屬性,導(dǎo)航屬性中包含與此實體相關(guān)的其他實體
/// 導(dǎo)航屬性通常定義為virtual
/// </summary>
public virtual ICollection<Enrollment> Enrollments { get; set; }
//如果導(dǎo)航屬性可以具有多個實體 (如多對多或一對多關(guān)系),那么導(dǎo)航屬性的類型必須是可以添加、 刪除和更新條目的容器,如 ICollection。
}
- 創(chuàng)建數(shù)據(jù)庫上下文
/// <summary>
/// 必須要繼承DbContext此類
/// </summary>
public class SchoolContext : DbContext
{
/// <summary>
/// 連接字符串 (它稍后將添加到 .config 文件) 的名稱被傳遞給構(gòu)造函數(shù)
/// 使用 Code First 與 app.config/web.config 文件中的連接字符串
/// </summary>
public SchoolContext() : base("SchoolContext")
{
}
//DbContext 知道要加載現(xiàn)有模型 (而不是使用 Code First 計算從代碼) 的連接字符串是包含要使用的模型的詳細信息的 EF 連接字符串
//public SchoolContext() : base("name=SchoolContext")
//{
//}
//設(shè)置初始化數(shù)據(jù)庫
//當(dāng)?shù)谝淮问褂胐bContext派生類的實例時,此接口的實現(xiàn)用于初始化基礎(chǔ)數(shù)據(jù)庫。此初始化可以有條件地
//創(chuàng)建數(shù)據(jù)庫和/或為其輸入數(shù)據(jù)。所使用的策略是使用數(shù)據(jù)庫類的靜態(tài)初始化策略屬性設(shè)置的
static SchoolContext() {
//一:數(shù)據(jù)庫不存在時重新創(chuàng)建數(shù)據(jù)庫[默認(rèn)]
Database.SetInitializer(new CreateDatabaseIfNotExists<SchoolContext>());
//二:每次啟動應(yīng)用程序時創(chuàng)建數(shù)據(jù)庫
//Database.SetInitializer<SchoolContext>(new DropCreateDatabaseAlways<SchoolContext>());
//三:策略三:模型更改時重新創(chuàng)建數(shù)據(jù)庫
//Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SchoolContext>());
//策略四:從不創(chuàng)建數(shù)據(jù)庫
//Database.SetInitializer<SchoolContext>(null);
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
/// <summary>
/// 阻止表名正在變?yōu)閺?fù)數(shù)形式
/// </summary>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
- 啟用 Code First 遷移
- 從“工具”菜單中,選擇“NuGet 包管理器” > “包管理器控制臺”。
- 在PM>提示符處輸入以下命令:
//命令創(chuàng)建遷移文件夾的項目,在該文件夾中放入Configuration.cs可編輯以配置 Migrations 的文件
// Configuration類 Seed 方法 插入或更新后 Code First 創(chuàng)建或更新數(shù)據(jù)庫測試數(shù)據(jù)。 創(chuàng)建數(shù)據(jù)庫和每次更新數(shù)據(jù)庫架構(gòu)時,數(shù)據(jù)模型更改后調(diào)用方法,Seed方法運行每次執(zhí)行update-database命令
enable-migrations
// 創(chuàng)建測試數(shù)據(jù)
//protected override void Seed(ContosoUniversity.DAL.SchoolContext context)
//{
// var students = new List<Student>
// {
// new Student { FirstMidName = "Carson", LastName = "Alexander",
// EnrollmentDate = DateTime.Parse("2010-09-01") },
// ......
// }
// students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
// context.SaveChanges();
//}
//遷移生成的代碼 在名為的文件*<時間戳>_InitialCreate.cs*。 Up方法InitialCreate類創(chuàng)建與數(shù)據(jù)模型實體集相對應(yīng)的數(shù)據(jù)庫表和Down方法中刪除它們
add-migration InitialCreate
- update-database
//update-database命令將運行Up方法來創(chuàng)建數(shù)據(jù)庫,然后將它運行Seed方法來填充該數(shù)據(jù)庫
update-database
//查看應(yīng)用于目標(biāo)數(shù)據(jù)庫的SQL語句
Update-Database -Verbose
//數(shù)據(jù)庫版本回溯
Update-Database –TargetMigration:"遷移代碼文件名稱"