EF對於已有資料庫的Code First支持 原文鏈接 本文將逐步介紹怎樣用Code First的方式基於已有資料庫進行開發。Code First支持你使用C#或者VB.Net定義類.並使用數據模型標識和Fluent API定義與配置模型。 前提 已經安裝 Visual Studio 2012 或者 ...
EF對於已有資料庫的Code First支持
本文將逐步介紹怎樣用Code First的方式基於已有資料庫進行開發。Code First支持你使用C#或者VB.Net定義類.並使用數據模型標識和Fluent API定義與配置模型。
前提
已經安裝 Visual Studio 2012 或者 Visual Studio 2013
同時,你還需要安裝Entity Framework Tools for Visual Studio的6.1或更高版本。請參考Get Entity Framework
1. 創建一個資料庫
因為本文是研究基於已有資料庫進行Code First,所以,我們先創建一個資料庫作為我們的操作目標。(至於創建資料庫的過程,可以去 原文鏈接 看圖操作,這部分內容我就不翻譯了)
Let’s go ahead and generate the database.
-
Open Visual Studio
-
View -> Server Explorer
-
Right click on Data Connections -> Add Connection…
-
If you haven’t connected to a database from Server Explorer before you’ll need to select Microsoft SQL Server as the data source
- Connect to your LocalDb instance ((localdb)\v11.0), and enter Blogging as the database name
- Select OK and you will be asked if you want to create a new database, select Yes
-
The new database will now appear in Server Explorer, right-click on it and select New Query
-
複製以下代碼,到資料庫管理器中執行,以生成新的數據表
CREATE TABLE [dbo].[Blogs] (
[BlogId] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (200) NULL,
[Url] NVARCHAR (200) NULL,
CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
);
CREATE TABLE [dbo].[Posts] (
[PostId] INT IDENTITY (1, 1) NOT NULL,
[Title] NVARCHAR (200) NULL,
[Content] NTEXT NULL,
[BlogId] INT NOT NULL,
CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([PostId] ASC),
CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE
);
INSERT INTO [dbo].[Blogs] ([Name],[Url])
VALUES ('The Visual Studio Blog', 'http://blogs.msdn.com/visualstudio/')
INSERT INTO [dbo].[Blogs] ([Name],[Url])
VALUES ('.NET Framework Blog', 'http://blogs.msdn.com/dotnet/')
2.創建應用程式
依然基於簡單原則,我們還是創建一個控制台應用程式,並用Code First進行資料庫操作:
- 打開 Visual Studio
- 文件 -> 新建 -> 項目…
- 選擇控制台應用程式
- 輸入 CodeFirstExistingDatabaseSample 作為項目名
- 點擊確定
3.逆向工程
我們將使用Entity framework Tools for Visual Studio來生成一些基於資料庫的初始化代碼。當然,你也可以手動創建這些代碼。
-
項目 -> 添加新項…
-
從左側菜單的數據(Data)分類中選擇Ado.net 實體模型(Ado.net Entity Data Model)(目前我的電腦上沒裝中文版,在菜單中具體顯示的選項是什麼 可能會不太精確,這裡我只能是把大概意思譯一下,請見諒,謝謝。)
-
將新文件命名為 BloggingContext 並點擊確定
-
這時會啟動實體模型創建嚮導
-
選擇從資料庫創建模型(Code First from DataBase) 並點擊下一步
- 創建連接並點擊下一步
- 選擇要導入的數據表並點擊完成
當逆向工程完成後,項目中會自動生成一些文件,現在讓我們看看到底添加了一些什麼內容吧。
配置文件
在項目根目錄下添加了一個App.config
的文件,這個文件中包含了一個有關目標資料庫的連接字元串.
<connectionStrings>
<add
name="BloggingContext"
connectionString="data source=(localdb)\v11.0;initial catalog=Blogging;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
你還會註意到配置文件中的其他一些設置,這些是預設的EF設置,它告訴Code First在哪裡創建資料庫。 由於我們正在映射到現有資料庫,因此我們的應用程式將忽略這些設置。
衍生(派生)DbContext
在項目目錄下添加了一個名為BloggingContext的文件。這是與數據交互的上下文,通過它我們可以從資料庫中查詢數據或保存數據到資料庫。同時,BloggingContext為每一個表公開了一個DbSet<TEntity>屬性。 您還會註意到,預設構造函數使用 name = syntax語法調用基礎構造函數。 這是告訴Code First,應該從配置文件基於連接字元串名稱載入用於此上下文的連接字元串。
public partial class BloggingContext : DbContext
{
public BloggingContext()
: base("name=BloggingContext")
{
}
public virtual DbSet<Blog> Blogs { get; set; }
public virtual DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
當您在配置文件中使用連接字元串時,應始終使用name = syntax。 這樣可以確保如果連接字元串不存在,那麼Entity Framework將拋出異常而不是按照慣例創建一個新的資料庫。
實體模型類
最後,一個Blog和Post類也被添加到項目中。 這些是構成我們模型的實體類。 你將看到應用於類的數據模型標識配置,其中Code First約定與現有資料庫的結構不一致。 例如,你在Blog.Name和Blog.Url上看到StringLength特性,因為它們在資料庫中的最大長度為200(Code First 預設是使用資料庫提供程式支持的最大長度 - nvarchar(max))(你可以嘗試一下用Code First創建一個新的數據表,其中的string類型欄位不用StringLength或MaxLength進行標識,你會發現,在資料庫中自動生成的這個欄位的類型就是nvarchar(max))。
public partial class Blog
{
public Blog()
{
Posts = new HashSet<Post>();
}
public int BlogId { get; set; }
[StringLength(200)]
public string Name { get; set; }
[StringLength(200)]
public string Url { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
4.讀寫數據
現在,數據模型的逆向工程完成了,是時候與資料庫交互進行一些數據訪問了。在Main函數中實現如下代碼:
這段代碼的意思是創建一個新的 DbContext的對象實例,再用它去插入一個新的Blog對象到資料庫.再用Linq to Sql 從資料庫中查詢所有的Blogs,並按 Name 屬性排序。 在此過程中你完全感覺不到你在操作資料庫,是的,你就是在操作面向對象語言,EF幫你實現了與資料庫的所有交互
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 Blog
All blogs in the database:
.NET Framework Blog
ADO.NET Blog
The Visual Studio Blog
Press any key to exit...
Customizing the Scaffolded Code
For information on customizing the code that is generated by the wizard, see Customizing Code First to an Existing Database.
What if My Database Changes?
The Code First to Database wizard is designed to generate a starting point set of classes that you can then tweak and modify. If your database schema changes you can either manually edit the classes or perform another reverse engineer to overwrite the classes.
Using Code First Migrations with an Existing Database
If you want to use Code First Migrations with your existing database, see Code First Migrations with an existing database.
Summary
In this walkthrough we looked at Code First development using an existing database. We used the Entity Framework Tools for Visual Studio to reverse engineer a set of classes that mapped to the database and could be used to store and retrieve data.