網站首頁 編程語言 正文
EF的核心程序集位于System.Data.Entity.dll和System.Data.EntityFramework.dll中。
支持CodeFirst的位于EntityFramework.dll中。
通常使用NuGet Package Manager來添加這些程序集。
如果沒有數據庫:
- 1、先寫代碼,自動創建數據庫。
- 2、如果代碼有變化,自動刪除數據庫重建,或者是使用遷移功能更改已有數據庫。
如果已有數據庫:
- 使用EF PowerTools反向工程生成模型。
下面的示例程序中將通過一個控制臺程序演示如何通過Code First模式創建一個數據庫,并執行簡單的增刪改查操作。
一、創建一個控制臺應用程序,命名為CodeFirstAppDemo。
二、安裝Entity Framework,添加對Code First的支持
1、通過Nuget包管理器控制臺進行安裝
選擇“工具”->Nuget程序包管理器->程序包管理器控制臺,下面將會打開程序包管理器控制臺窗口:
輸入命令:Install-Package EntityFramework進行安裝。
2、通過可視化界面進行安裝
在項目上面右鍵選擇管理Nuget程序包:
選擇EntityFramework,點擊“安裝”按鈕進行安裝:
安裝完以后,項目引用里面將會出現EntityFramework程序集:
如果安裝完以后,項目引用里面沒有這兩個dll,一定要檢查為什么沒有安裝成功,因為下面的程序中要用到DbContext類,該類位于EntityFramework程序集中。
三、根據.NET中的類來創建數據庫。
經過上面的步驟之后,我們就可以開始寫代碼了。在寫代碼之前,要始終記得:每個實體類就是相應的數據表中的一行數據,該實體類的屬性對應的就是數據表中的列。
1、創建EDM實體數據模型
在項目上右鍵->添加->新建文件夾,命名為Models,存放相應的實體類。在Models文件夾下面新建兩個實體類:Category和Product,Category里面包含一個類型是Product的集合屬性,兩個實體類的屬性分別如下:
Category類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirstAppDemo.Models { ////// 產品分類表 /// public class Category { ////// 分類ID /// public int CategoryId { get; set; } ////// 分類名稱 /// public string CategoryName { get; set; } ////// 產品 /// public ListProductList { get; set; } } }
Produce類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirstAppDemo.Models { ////// 產品類 /// public class Product { ////// 產品Id /// public int Id { get; set; } ////// 產品名稱 /// public string ProductName { get; set; } ////// 產品價格 /// public decimal Price { get; set; } ////// 出版日期 /// public DateTime PublicDate { get; set; } } }
我們需要定義和期望的數據庫類型相匹配的屬性。上面的例子中,.Net中的int類型會映射到SQL Server中的int類型,string類型會映射到所有可能的字符類型,decimal和Datetime也和SQL Server中的一樣。大多數時候,我們不需要關心這些細節,我們只需要編寫能夠表示數據的模型類就行了,然后使用標準的.Net類型定義屬性,其他的就讓EF自己計算出保存數據所需要的RDBMS類型。
2、創建數據上下文
接下來我們創建數據庫上下文,它是數據庫的抽象。目前,我們有兩張張表Category和Product,因而要給該數據庫上下文定義兩個屬性來代表這兩張表。再者,一張表中一般肯定不止一條數據行,所以我們必須定義一個集合屬性,EF使用DbSet來實現這個目的。
在項目上右鍵->添加->新建文件夾,命名為EFDbContext,用來存放數據庫上下文類。添加類Context,并使該類繼承自DbContext類。DbContext位于EntityFramework.dll程序集中。
Context類代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Entity; using CodeFirstAppDemo.Models; namespace CodeFirstAppDemo.EFDbContext { public class Context : DbContext { ////// 1、創建構造函數,構造函數繼承DbContext類的構造函數,通過DbContext類的構造函數創建數據庫連接 /// 2、DbContext類的構造函數里面的參數是數據庫連接字符串,通過該連接字符串去創建數據庫 /// public Context() : base("name=FirstCodeFirstApp") { } //2、定義數據集合:用于創建表 public DbSetCategorys { get; set; } public DbSet Products { get; set; } } }
在這里,DbContext是所有基于EF的上下文基類,通過它可以訪問到數據庫中的所有表。上面的代碼中調用了父類的構造函數,并且傳入了一個鍵值對,鍵是name,值是CodeFirstApp,這個鍵值對是定義在應用程序的配置文件中的,取決于你的應用程序類型,可能是app.config或者web.config。在我們的控制臺應用程序中就是app.config。
在app.config文件的configuration節點下(不要在第一個節點下,否則會報錯)添加:
3、使用EF提供的API訪問數據庫來創建數據庫
using CodeFirstAppDemo.EFDbContext; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirstAppDemo { class Program { static void Main(string[] args) { // 使用數據庫上下文Context using (var context = new Context()) { // 如果數據庫不存在,則調用EF內置的API創建數據庫 if (context.Database.CreateIfNotExists()) { Console.WriteLine("數據庫創建成功!"); } else { Console.WriteLine("數據庫已存在"); } } Console.ReadKey(); } } }
最后,只需要確保連接字符串沒有問題就可以了。運行程序,然后打開SSMS進行確認數據庫是否創建成功即可。
這時可以清楚地看到,數據庫表名是自定義數據庫上下文中DbSet
四、執行簡單的CRUD操作
1、創建記錄-Create
你可以這樣認為,將對象添加到集合中就相當于將數據插入到數據庫相應的表中。我們使用DbSet的Add方法來實現新數據的添加,而DbContext類的SaveChanges方法會將未處理的更改提交到數據庫,這是通過檢測上下文中所有的對象的狀態來完成的。所有的對象都駐留在上下文類的DbSet屬性中。比如,例子中有一個Products屬性,那么所有的產品數據都會存儲到這個泛型集合屬性中。數據庫上下文會跟蹤DbSet屬性中的所有對象的狀態,這些狀態有這么幾種:Deleted、Added、Modified和Unchanged。如果你想在一個表中插入多行數據,那么只需要添加該表對應的類的多個對象的實例即可,然后使用SaveChanges方法將更改提交到數據庫,該方法是以單事務執行的。最終,所有的數據庫更改都會以單個工作單元持久化。既然是事務,那么就允許將批量相關的更改作為單個操作提交,這樣就保證了事務一致性和數據完整性。
修改Main方法如下:
using CodeFirstAppDemo.EFDbContext; using CodeFirstAppDemo.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirstAppDemo { class Program { static void Main(string[] args) { // 使用數據庫上下文Context using (var context = new Context()) { // 如果數據庫不存在,則調用EF內置的API創建數據庫 if (context.Database.CreateIfNotExists()) { Console.WriteLine("數據庫創建成功!"); } else { Console.WriteLine("數據庫已存在"); } #region EF 添加數據 //添加數據 var cate = new List{ new Category{ CategoryName="文學類", ProductList=new List { new Product { ProductName="百年孤獨", Price=37.53m, PublicDate=new DateTime(2011,6,1) }, new Product { ProductName="老人與海", Price=37.53m, PublicDate=new DateTime(2010,6,1) } } }, new Category{ CategoryName="計算機類", ProductList=new List { new Product { ProductName="C#高級編程第九版", Price=48.23m, PublicDate=new DateTime(2016,2,8) }, new Product { ProductName="Oracle從入門到精通", Price=27.03m, PublicDate=new DateTime(2014,7,9) } } } }; //將創建的集合添加到上下文中 context.Categorys.AddRange(cate); //調用SaveChanges()方法,將數據插入到數據庫 context.SaveChanges(); #endregion } Console.ReadKey(); } } }
這里需要注意兩點:
1、不需要給Product.Id屬性賦值,因為它對應到SQL Server表中的主鍵列,它的值是自動生成的,當SaveChanges執行以后,打斷點就能看到返回的Product.Id已經有值了。
2、Context的實例用了using語句包裝起來,這是因為DbContext實現了IDisposable接口。DbContext還包含了DbConnection的實例,該實例指向了具有特定連接字符串的數據庫。在EF中合適地釋放數據庫連接和ADO.NET中同等重要。
2、查詢記錄-Retrieve
查詢時也是直接通過DbSet進行查詢的:
using CodeFirstAppDemo.EFDbContext; using CodeFirstAppDemo.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirstAppDemo { class Program { static void Main(string[] args) { // 使用數據庫上下文Context using (var context = new Context()) { // 如果數據庫不存在,則調用EF內置的API創建數據庫 if (context.Database.CreateIfNotExists()) { Console.WriteLine("數據庫創建成功!"); } else { Console.WriteLine("數據庫已存在"); } #region EF 2查詢數據 //查詢方式1 var products = from p in context.Categorys select p; foreach (var item in products) { Console.WriteLine("分類名稱:" + item.CategoryName); } //查詢方式2 //延遲加載 cates里面沒有數據 var cates = context.Categorys; //執行迭代的時候才有數據 foreach (var item in cates) { Console.WriteLine("分類名稱:" + item.CategoryName); } #endregion } Console.ReadKey(); } } }
如果像下面那樣打一個斷點,你會看到一個結果視圖,點擊類似刷新的圖標會看到查詢的結果,這個東西道出了EF中很重要的一個概念:延遲加載。此時還沒有真正查詢數據庫,只有當LINQ的查詢結果被訪問或者被枚舉時才會將查詢命令發送到數據庫。EF是基于DbSet實現的IQueryable接口來處理延遲查詢的。
3、更新記錄-Update
在SQL中,更新需要執行Update命令。而在EF中,我們要找到DbSet實體集合中要更新的對象,然后修改其屬性,最后調用SaveChanges方法即可。
using CodeFirstAppDemo.EFDbContext; using CodeFirstAppDemo.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CodeFirstAppDemo { class Program { static void Main(string[] args) { // 使用數據庫上下文Context using (var context = new Context()) { // 如果數據庫不存在,則調用EF內置的API創建數據庫 if (context.Database.CreateIfNotExists()) { Console.WriteLine("數據庫創建成功!"); } else { Console.WriteLine("數據庫已存在"); } #region EF 更新數據 var products = context.Products; if (products.Any()) { // 查詢產品名稱是“百年孤獨”的產品 var toUpdateProduct = products.First(p => p.ProductName == "百年孤獨"); // 修改查詢出的產品名稱 toUpdateProduct.ProductName = "唐詩三百首"; // 調用SaveChanges()方法保存數據 context.SaveChanges(); } #endregion } Console.ReadKey(); } } }
這里我們使用了Any()擴展方法來判斷序列中是否有元素,然后使用First()擴展方法來找到Name=="百年孤獨"的元素,然后給目標對象的Name屬性賦予新值,最后調用SaveChanges()方法保存數據。
4、刪除記錄-Delete
要刪除一條數據,就要先找到這條數據.
using CodeFirstAppDemo.EFDbContext; using CodeFirstAppDemo.Models; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; namespace CodeFirstAppDemo { class Program { static void Main(string[] args) { // 使用數據庫上下文Context using (var context = new Context()) { // 如果數據庫不存在,則調用EF內置的API創建數據庫 if (context.Database.CreateIfNotExists()) { Console.WriteLine("數據庫創建成功!"); } else { Console.WriteLine("數據庫已存在"); } #region EF 刪除數據 var products = context.Products; // 先根據ProductName找到要刪除的元素 var toDeleteProduct = context.Products.Single(p => p.ProductName == "唐詩三百首"); if (toDeleteProduct != null) { // 方式1:使用Remove()方法移除 context.Products.Remove(toDeleteProduct); // 方式2:更改數據的狀態 context.Entry(toDeleteProduct).State = EntityState.Deleted; // 最后持久化到數據庫 context.SaveChanges(); #endregion } Console.ReadKey(); } } }
原文鏈接:https://www.cnblogs.com/dotnet261010/p/7119351.html
相關推薦
- 2022-12-13 sql索引失效的情況以及超詳細解決方法_MsSql
- 2022-09-18 go?mock?server的簡易實現示例_Golang
- 2021-12-01 C語言多維數組數據結構的實現詳解_C 語言
- 2022-03-15 C語言if選擇結構語句詳解_C 語言
- 2022-11-26 React?DnD如何處理拖拽詳解_React
- 2022-05-12 tp5使用阿里云oss存儲圖片
- 2022-09-14 iOS開發多線程下全局變量賦值崩潰原理詳解_IOS
- 2022-12-26 .NET?6實現滑動驗證碼的示例詳解_實用技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支