EntityFramework是微軟推出的一款ORM工具,關於ORM的概念請參考博客http://www.javashuo.com/article/p-dyrdltpl-dx.html。這篇文章對ORM進行很詳細的介紹。簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係數據庫中。html
在.NET3.5以前咱們從數據庫檢索或者存儲數據的方式常常都是ADO.NET。操做數據會經歷以下步驟,打開數據庫鏈接,建立一個數據集來獲取或提交數據到數據庫,將數據集中的數據轉換爲.NET對象。或者反過來應用業務規則。這是一個繁瑣且重複的工做,或許會有一些Helper來幫助咱們解決數據庫鏈接方面的工做,可是數據集到領域對象的過程是咱們須要一次次去映射的。因此,ORM工具就提供給了咱們操做業務對象,由ORM對咱們操做的對象進行數據庫操做映射。EntityFramework就是這樣的一種工具,咱們使用Linq操做領域對象,EntityFramework會幫咱們將對應操做轉換爲SQL語句,而後鏈接到數據庫執行。這樣咱們就能夠在更高的抽象層面來處理數據,而且與傳統應用程序相比,能夠用更少的代碼建立和維護面向數據的應用程序。關於EntityFramework的概念和介紹能夠參考MSDN或者http://www.entityframeworktutorial.net/what-is-entityframework.aspx。以上部分概念也來源於此網站。另外,EntityFramework Core爲EF垮平臺版本。好了,下面進入EntityFramework的具體使用部分。數據庫
EntityFramework有3中使用模式app
下面咱們依次來看看3種模式在實際的編碼過程當中怎麼使用,示例程序使用SQL Server2016數據庫引擎,Northwind數據庫。開發工具爲VS2017。ide
1,建立控制檯應用Demo.DatabaseFirst函數
2,安裝EntityFramework Nuget包,示例程序版本爲6.2.0工具
3,添加實體數據模型,在Data模板下選擇ADO.NET實體數據模型,命名爲DemoModel學習
4,由於咱們是從數據庫生成實體數據模型,因此,咱們選擇來自數據庫的EF設計器開發工具
5,進行數據庫配置,因爲我這裏以前配置過數據庫,因此會有以前的鏈接信息,此處,咱們新建數據庫鏈接,點擊新建鏈接網站
6,配置數據鏈接,並選擇數據庫。在高級選項中,有關於鏈接配置的選項,能夠根據須要修改。ui
7,配置完成後,點擊下一步選擇須要生成實體數據模型的表(視圖,存儲過程或者函數)
8,點擊完成,此時,從數據庫映射的實體數據模型已經生成。咱們能夠看一下,在解決方案結構中,EF幫咱們新建了哪些文件,在配置文件中又幫咱們加入了哪些內容
DemoModel.edmx就是EF幫咱們生成的數據模型,雙擊以後,咱們能夠看到咱們選中的表已經映射成爲了實體數據模型。生成模型的規則是EF定義的模板文件(XXX.tt),不一樣的EF版本有不一樣的模板文件,咱們也能夠自定義模板文件。咱們右鍵點擊某個模型,能夠看到以下圖的菜單。從數據庫更新模型,當數據庫發生更改的時候,咱們能夠經過點擊此菜單來將數據庫的更改映射到模型。表映射能夠查看實體數據類型與表的映射,屬性與列信息的映射信息等等。咱們也能夠查看數據模型的屬性,在空白處點擊右鍵,選擇屬性。能夠看到數據模型的選項,有數據庫的鏈接字符串信息,是否延遲加載等等,能夠根據需求自行更改配置。
實體關係:從edmx設計中能夠看到,實體之間的鏈接線有1…*,*…*,0..1的關聯屬性,這些關係實際上映射的就是數據庫中表之間的關係,也就是咱們常說的,一對一,多對多,一對多。實體數據模型會根據數據庫中的主外鍵信息自動生成關係模型數據。選中鏈接線,右鍵查看屬性,能夠查看實體之間關係的具體信息。
導航屬性:上面說了,實體與實體之間是存在關係的,那麼怎麼從一個實體去訪問另一個與他有關係的實體呢,實際上咱們經過導航屬性。導航屬性實際上就是實現了從一個實體到另外一個關聯實體的訪問機制。
實體數據模型實際上包含了實體對象信息,數據庫元數據信息,對象與數據庫的映射信息。那麼這些信息是在哪裏定義的呢,咱們使用文本編輯工具打開DemoModel.edmx文件,能夠看到edmx其實是一個xml文件,這個xml文件的主要節點以下
1,edmx:StorageModels(邏輯層SSDL):SSDL主要定義了數據庫中表,列,關係,視圖,函數等
2,emdx:ConceptualModels(概念層CSDL):CSDL主要定義了數據模型的實體類型,這些實體暴露給上層來操做實體數據
3,edmx:Mappings(映射層):SSDL與CSDL之間的關係映射
EntityFramework使用了上述的xml文件定義了,實體,數據庫對象,與他們之間的關係。至此,咱們完成了EntityFramework的實體數據映射並分析了基本原理。定義數據模型的意義在於操做數據,下面咱們使用數據模型來進行數據的增刪改查。咱們新建類CategoryServices,並添加AddCategory,UpdateCategory,DeleteCatetory,GetCatetories四個方法
public bool AddCategory(Category category) { using (NorthwindEntities context = new NorthwindEntities()) { context.Categories.Add(category); return context.SaveChanges()>0; } }
public bool UpdateCategory(Category category) { bool reuslt = false; using (NorthwindEntities context = new NorthwindEntities()) { Category currentCategory = context.Categories .FirstOrDefault(parm => parm.CategoryID == category.CategoryID); if (currentCategory != null) { currentCategory.Description = category.Description; reuslt = context.SaveChanges() > 0; } return reuslt; } }
public bool DeleteCatetory(int id) { bool reuslt = false; using (NorthwindEntities context = new NorthwindEntities()) { Category currentCategory = context.Categories .FirstOrDefault(parm => parm.CategoryID == id); if (currentCategory != null) { context.Categories.Remove(currentCategory); reuslt = context.SaveChanges() > 0; } return reuslt; } }
public List<Category> GetCatetories() { using (NorthwindEntities context = new NorthwindEntities()) { return context.Categories.ToList(); } }
class Program { static void Main(string[] args) { CategoryServices services = new CategoryServices(); List<Category> categories = services.GetCatetories(); categories.ForEach(parm => Console.WriteLine($"{parm.CategoryName}---{parm.Description}")); Console.WriteLine("---select---"); Category category = new Category { CategoryName = "Microsoft", Description = "this is Microsoft" }; bool result = services.AddCategory(category); Category categoryAdd = services.GetCatetories().LastOrDefault(); Console.WriteLine($"{categoryAdd.CategoryName}---{categoryAdd.Description}"); Console.WriteLine("---add---"); Category categoryUpdate = new Category { CategoryID = categoryAdd.CategoryID, CategoryName = "Microsoft", Description = "this is Microsoft update" }; bool updateResult = services.UpdateCategory(categoryUpdate); Console.WriteLine($"{categoryUpdate.CategoryName}---{categoryUpdate.Description}"); Console.WriteLine("---update---"); int catetoryId = categoryAdd.CategoryID; bool deleteUpdate = services.DeleteCatetory(catetoryId); Category categoryLast = services.GetCatetories().LastOrDefault(); Console.WriteLine($"{categoryLast.CategoryName}---{categoryLast.Description}"); Console.WriteLine("---delete---"); Console.ReadLine(); } }
以下圖執行結果,第一步咱們打印了全部的Category,第二步咱們添加一條Category,緊接着咱們修改了添加的這條數據,最後咱們刪除這條數據。能夠看到,增刪改查操做完成。是否是感受操做數據庫也能夠像操做對象同樣簡單,便捷。
DbContext:上面的實例中,咱們實例化了類型NorthwindEntities。這個在咱們配置數據庫鏈接的時候輸入的上下文名稱。實際上,在EntityFramework幫助咱們生成數據模型時,也同時幫咱們生成了繼承與DbContext類型的數據上下文,咱們這裏是NorthwindEntities。那麼數據上下文是什麼呢。數據上下文實際是真實與數據庫交互的橋樑。前面的章節咱們定義了對象,數據,映射,這些都是基礎設施,也是基礎結構。在操做數據時,好比添加數據。最終數據庫能執行的操做只會是SQL語句,存儲過程等。因此 ,數據上下文監測了咱們對實體類型的更改,在調用SaveChange時將咱們對上下文中實體的更改轉換成SQL語句發送給數據庫執行,咱們能夠打開SQL Server監視工具來查看EntityFrameworkSaveChange後生成的SQL語句。因此,在瞭解了ORM的核心概念後,其實,若是咱們願意,也能夠本身實現一套ORM工具。
下面的代碼就是EntityFramework生成的繼承自DbContext的數據上下文。
namespace Demo.DatabaseFirst { using System; using System.Data.Entity; using System.Data.Entity.Infrastructure; public partial class NorthwindEntities : DbContext { public NorthwindEntities() : base("name=NorthwindEntities") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCodeFirstException(); } public virtual DbSet<Category> Categories { get; set; } public virtual DbSet<CustomerDemographic> CustomerDemographics { get; set; } public virtual DbSet<Customer> Customers { get; set; } public virtual DbSet<Employee> Employees { get; set; } public virtual DbSet<Order_Detail> Order_Details { get; set; } public virtual DbSet<Order> Orders { get; set; } public virtual DbSet<Product> Products { get; set; } public virtual DbSet<Region> Regions { get; set; } public virtual DbSet<Shipper> Shippers { get; set; } public virtual DbSet<Supplier> Suppliers { get; set; } public virtual DbSet<Territory> Territories { get; set; } } }
好了,至此,EntityFramework的基本概念和Database First基本操做已經完成,因爲水平有限,若是在講解過程當中有任何錯誤請留言告知,在學習與記錄的過程與你們共同進步。下一篇會講解EntityFramework的Model First。