EntityFramwork(1) 源地址https://msdn.microsoft.com/zh-cn/data/jj193542
1.創建應用程序
簡單起見,我們將構建一個使用 Code First 執行數據訪問的基本控制臺應用程序。
- 打開 Visual Studio
- "文件"->"新建"->"項目…"
- 從左側菜單中選擇"Windows"和"控制臺應用程序"
- 輸入?CodeFirstNewDatabaseSample?作為名稱
- 選擇"確定"
? ?
2.創建模型
我們使用類來定義一個非常簡單的模型。在 Program.cs 文件中進行定義,但是實際應用程序中,可能會將類分為若干個單獨的文件,可能作為單獨的項目。
在 Program.cs 中的程序類定義下,添加以下兩個類。
public?class?Blog?
{?
????public?int?BlogId?{?get;?set;?}?
????public?string?Name?{?get;?set;?}?
?
????public?virtual?List<Post>?Posts?{?get;?set;?}?
}?
?
public?class?Post?
{?
????public?int?PostId?{?get;?set;?}?
????public?string?Title?{?get;?set;?}?
????public?string?Content?{?get;?set;?}?
?
????public?int?BlogId?{?get;?set;?}?
????public?virtual?Blog?Blog?{?get;?set;?}?
}
可以看到,我們將虛擬化兩個導航屬性(Blog.Posts 和 Post.Blog)。這將啟用實體框架的延遲加載功能。延遲加載意味著,嘗試訪問這些屬性的內容時,將自動從數據庫加載。
? ?
3.創建上下文
現在,可以定義派生上下文,用于表示數據庫的一個會話,以便我們查詢和保存數據。我們定義一個派生自 System.Data.Entity.DbContext 的上下文,并為模型中的每個類公開一個類型化 DbSet<TEntity>。
現在,開始使用來自實體框架的類型。因此,我們需要添加 EntityFramework NuGet 程序包。
- "項目"–>"管理 NuGet 程序包…"
注意:如果沒有"管理 NuGet 程序包…"選項,則應安裝?最新版本的 NuGet - 選擇"聯機"選項卡
- 選擇"EntityFramework"程序包
- 單擊"安裝"
在 Program.cs 頂部,為 System.Data.Entity 添加一個 using 語句。
using?System.Data.Entity;
在 Program.cs 中的 Post 類下,添加以下派生上下文。
public?class?BloggingContext?:?DbContext?
{?
????public?DbSet<Blog>?Blogs?{?get;?set;?}?
????public?DbSet<Post>?Posts?{?get;?set;?}?
}
下面是 Program.cs 現在應包含內容的完整列表。
using?System;?
using?System.Collections.Generic;?
using?System.Linq;?
using?System.Text;?
using?System.Threading.Tasks;?
using?System.Data.Entity;?
?
namespace?CodeFirstNewDatabaseSample?
{?
????class?Program?
????{?
????????static?void?Main(string[]?args)?
????????{?
????????}?
????}?
?
????public?class?Blog?
????{?
????????public?int?BlogId?{?get;?set;?}?
????????public?string?Name?{?get;?set;?}?
?
????????public?virtual?List<Post>?Posts?{?get;?set;?}?
????}?
?
????public?class?Post?
????{?
????????public?int?PostId?{?get;?set;?}?
????????public?string?Title?{?get;?set;?}?
????????public?string?Content?{?get;?set;?}?
?
????????public?int?BlogId?{?get;?set;?}?
????????public?virtual?Blog?Blog?{?get;?set;?}?
????}?
?
????public?class?BloggingContext?:?DbContext?
????{?
????????public?DbSet<Blog>?Blogs?{?get;?set;?}?
????????public?DbSet<Post>?Posts?{?get;?set;?}?
????}?
}
這是我們開始存儲和檢索數據所需的全部代碼。顯然,后臺發生了許多事情。稍后,我們將進行了解。但是,首先讓我們看看它是如何運行的。
? ?
4.讀寫數據
實現 program.cs 中的 Main 方法,如下所示。這些代碼為上下文創建一個新實例,然后使用該實例插入新博客。之后,它使用 LINQ 查詢檢索數據庫中的所有博客(按標題的字母順序進行排序)。
class?Program?
{?
????static?void?Main(string[]?args)?
????{?
????????using?(var?db?=?new?BloggingContext())?
????????{?
????????????//?Create?and?save?a?new?Blog?
????????????Console.Write("Enter?a?name?for?a?new?Blog:?");?
????????????var?name?=?Console.ReadLine();?
?
????????????var?blog?=?new?Blog?{?Name?=?name?};?
????????????db.Blogs.Add(blog);?
????????????db.SaveChanges();?
?
????????????//?Display?all?Blogs?from?the?database?
????????????var?query?=?from?b?in?db.Blogs?
????????????????????????orderby?b.Name?
????????????????????????select?b;?
?
????????????Console.WriteLine("All?blogs?in?the?database:");?
????????????foreach?(var?item?in?query)?
????????????{?
????????????????Console.WriteLine(item.Name);?
????????????}?
?
????????????Console.WriteLine("Press?any?key?to?exit...");?
????????????Console.ReadKey();?
????????}?
????}?
}
現在,可以運行應用程序,對其進行測試。
Enter a name for a new Blog:?ADO.NET 博客 |
? ?
我的數據在哪里?
按照約定,DbContext 已經創建了一個數據庫。
- 如果本地 SQL Express 實例可用(默認情況下隨 Visual Studio 2010 安裝),則 Code First 已對該實例創建了數據庫
- 如果 SQL Express 不可用,則 Code First 將嘗試使用?LocalDb(默認情況下隨 Visual Studio 2012 安裝)
- 數據庫以派生上下文的完全限定名命名,在我們的示例中,名稱為?CodeFirstNewDatabaseSample.BloggingContext
這些僅僅是默認約定,除此之外,還有多種方式可更改 Code First 所用的數據庫。有關更多信息,請參見DbContext 如何發現模型和數據庫連接?主題。
? ?
可以在 Visual Studio 中使用服務器資源管理器連接至此數據庫
- "視圖"->"服務器資源管理器"
- 右鍵單擊"數據連接"并選擇"添加連接…"
- 如果尚未從服務器資源管理器連接至數據庫,則需要選擇 Microsoft SQL Server 作為數據源
- 連接至 LocalDb ((localdb)\v11.0) 或 SQL Express (.\SQLEXPRESS),具體取決于安裝情況
? ?
現在,可以檢查 Code First 已經創建的架構。
DbContext 通過查看我們定義的 DbSet 屬性,了解模型包含哪些類。隨后,它使用 Code First 約定的默認集來確定表和列的名稱,確定數據類型,查找主鍵等。本演練稍后將介紹如何重寫這些約定。
? ?
5.處理模型更改
現在更改模型,當我們進行更改時,還需要更新數據庫架構。為此,我們使用一個稱為"Code First 遷移"(或簡稱"遷移")的功能。
"遷移"是一組有序的步驟,描述如何升級(和降級)數據庫架構。這些步驟(稱為"遷移")中的每個步驟均包含一些代碼,用于描述要應用的更改。?
第一步是為 BloggingContext 啟用 Code First 遷移。
- "工具"->"庫程序包管理器"->"程序包管理器控制臺"
- 在程序包管理器控制臺中運行?Enable-Migrations?命令
- 一個新的 Migrations 文件夾已添加至項目中,它包含兩個文件:
- Configuration.cs?— 此文件包含"遷移"將用來遷移 BloggingContext 的設置。在本演練中不需要進行任何更改,但是,在此處可以指定種子數據、為其他數據庫注冊提供程序、更改生成遷移的命名空間等。
- <時間戳>_InitialCreate.cs?— 這是第一個遷移,它表示已經應用于數據庫的更改。應用更改的目的是將其從空數據庫遷移至包含博客和文章表的數據庫。盡管我們讓 Code First 自動創建這些表,現在我們選擇"遷移"(已轉化為一次"遷移")。Code First 還在本地數據庫中記錄:該"遷移"已經應用。文件名中的時間戳用于排序。
現在,更改模型,向 Blog 類添加一個 Url 屬性:
public?class?Blog?
{?
????public?int?BlogId?{?get;?set;?}?
????public?string?Name?{?get;?set;?}?
????public?string?Url?{?get;?set;?}?
?
????public?virtual?List<Post>?Posts?{?get;?set;?}?
}
- 在程序包管理器控制臺中運行?Add-Migration AddUrl?命令。
Add-Migration 命令檢查自上次遷移后是否有更改,并使用所有更改搭建新遷移。我們可以為遷移指定名稱;在本例中,將此遷移稱為"AddUrl"。
搭建的代碼表明:我們需要向 dbo.Blogs 表添加可容納字符串數據的 Url 列。如果需要,可以對搭建的代碼進行編輯,但是,在本例中,沒有這個必要。
namespace?CodeFirstNewDatabaseSample.Migrations?
{?
????using?System;?
????using?System.Data.Entity.Migrations;?
?????
????public?partial?class?AddUrl?:?DbMigration?
????{?
????????public?override?void?Up()?
????????{?
????????????AddColumn("dbo.Blogs",?"Url",?c?=>?c.String());?
????????}?
?????????
????????public?override?void?Down()?
????????{?
????????????DropColumn("dbo.Blogs",?"Url");?
????????}?
????}?
}
- 在程序包管理器控制臺中運行?Update-Database?命令。此命令將所有掛起的遷移應用于數據庫。InitialCreate 遷移已經應用,因此,這些遷移將僅應用新的 AddUrl 遷移。
提示:在調用 Update-Database 命令查看對數據庫執行的 SQL 時,可以使用?–Verbose?開關。
? ?
新的 Url 列已添加至數據庫中的 Blogs 表:
?
6.數據注釋
到目前為止,EF 發現了使用其默認約定的模型。但是,有時類不遵從約定,我們需要能夠執行進一步配置。對此有兩種方法;本節將介紹數據注釋,下一節將介紹 Fluent API。
- 向模型添加用戶類
public?class?User?
{?
????public?string?Username?{?get;?set;?}?
????public?string?DisplayName?{?get;?set;?}?
}
- 我們還需要向派生上下文添加一個集
public?class?BloggingContext?:?DbContext?
{?
????public?DbSet<Blog>?Blogs?{?get;?set;?}?
????public?DbSet<Post>?Posts?{?get;?set;?}?
????public?DbSet<User>?Users?{?get;?set;?}?
}
- 如果嘗試添加遷移,會收到錯誤消息"EntityType'User'未定義鍵。請為該 EntityType 定義鍵。"這是因為 EF 無法知道 Username 應為用戶的主鍵。
- 我們將使用數據注釋,因此需要在 Program.cs 的頂部添加一個 using 語句
using?System.ComponentModel.DataAnnotations;
- 現在,注釋 Username 屬性,將它標識為主鍵
public?class?User?
{?
????[Key]?
????public?string?Username?{?get;?set;?}?
????public?string?DisplayName?{?get;?set;?}?
}
- 使用?Add-Migration AddUser?命令搭建一個遷移,將這些更改應用于數據庫
- 運行?Update-Database?命令,將新遷移應用于數據庫
現在,新表已添加至數據庫:
? ?
EF 支持的完整注釋列表為:
- KeyAttribute
- StringLengthAttribute
- MaxLengthAttribute
- ConcurrencyCheckAttribute
- RequiredAttribute
- TimestampAttribute
- ComplexTypeAttribute
- ColumnAttribute
- TableAttribute
- InversePropertyAttribute
- ForeignKeyAttribute
- DatabaseGeneratedAttribute
- NotMappedAttribute
? ?
7.Fluent API
上一節介紹了如何使用數據注釋來補充或重寫按約定檢測的內容。另一種模型配置方法是通過 Code First Fluent API。
大多數模型配置都可使用簡單數據注釋進行。Fluent API 是一種更高級的方法,除某些數據注釋不可能支持的更高級配置外,可以指定包含數據注釋所有功能的模型配置。數據注釋和 Fluent API 可一起使用。
要訪問 Fluent API,需要在 DbContext 中重寫 OnModelCreating 方法。假設我們需要重命名 User.DisplayName 存儲至 display_name 的列。
- 使用以下代碼重寫 BloggingContext 的 OnModelCreating 方法
public?class?BloggingContext?:?DbContext?
{?
????public?DbSet<Blog>?Blogs?{?get;?set;?}?
????public?DbSet<Post>?Posts?{?get;?set;?}?
????public?DbSet<User>?Users?{?get;?set;?}?
?
????protected?override?void?OnModelCreating(DbModelBuilder?modelBuilder)?
????{?
????????modelBuilder.Entity<User>()?
????????????.Property(u?=>?u.DisplayName)?
????????????.HasColumnName("display_name");?
????}?
}
- 使用?Add-Migration ChangeDisplayName?命令搭建遷移,將這些更改應用于數據庫。
- 運行?Update-Database?命令,將新遷移應用于數據庫。
? ?
DisplayName 列現在重命名為 display_name:
轉載于:https://www.cnblogs.com/ljp-sun/p/4418270.html
總結
以上是生活随笔為你收集整理的EntityFramwork(1) 源地址https://msdn.microsoft.com/zh-cn/data/jj193542的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华硕推出新款无畏 15 2023 笔记本
- 下一篇: 啊啊啊 草蛋啊 之前努力一天搞出来的时间