使用EntityFramework6完成增刪查改和事務
上一節我們已經學習了如何使用EF連接數據庫,並簡單演示了一下如何使用EF6對數據庫進行操作,這一節我來詳細講解一下。
使用EF對數據庫進行操作,整個過程就像操作數組一樣,我們只管修改或向集合中添加值,最后通知EF保存修改后的結果就可以了。
准備工作
為了演示,我在數據庫中建了兩張表。class表用於表示班級,class_id是班級編號,class_name是班級名稱。第二張表是學生表student,student_id為學生編號,name為姓名,age為年齡,class_id是學生所屬班級,student表中的class_id與class表中的class_id存在外聯關系。
數據庫建好后,按照上一節介紹的步驟我們直接通過向導來生成EF代碼。
執行完成后VS為我們生成了三個類,分別是DBModel、_class、student,其中DBModel代表的是數據庫,而_class和student則分別代表班級表和學生表。
先來看看DBModel類,DBModel相當於一個數據庫,之后你new一個DBModel就相當於打開了一次數據庫,跟數據庫建立了一次連接。
再來看看student與_class類。類中的屬性上添加很多特性(Attribute),用於描述數據約束。值得注意的是在student類中,EF將我們的外鍵class_id分解成了兩個屬性,其中_class前面使用了virtual關鍵字,使用了virtual關鍵字描述的屬性在查詢時並不會馬上從數據庫中讀取數據,而是當你真正需要用到它的值時再單獨從數據庫中查詢出來。
使用EF讀取數據
我先在學生表中添加了一些數據。
接下來讓我們使用EF來查詢年齡大於10歲的同學的學號、姓名、年齡、班級名稱。
- class Program
- {
- static void Main(string[] args)
- {
- using (var db = new DBModel())
- {
- var result = from i in db.students //使用LINQ查詢年齡大於10歲的學生
- where i.age > 10
- select i;
- foreach (var student in result)
- {
- Console.WriteLine("學號:" + student.Student_id + " 姓名:" + student.name
- + " 年齡:" + student.age + " 班級名稱:" + student._class.class_name);
- }
- Console.Read();
- }
- }
- }
其中使用了LINQ,對LINQ不熟的可以看看這篇文章。
使用EF添加數據
向數據庫中添加數據就跟往List<>集合添加數據一樣,不過最后需要調用SaveChanges()向數據庫保存一下數據。
- class Program
- {
- static void Main(string[] args)
- {
- using (var db = new DBModel())
- {
- var s = new student();
- //因為數據庫中的student_id是自動增長的所以可以不用賦值
- s.name = "張三";
- s.age = 15;
- s.class_id = 1;
- db.students.Add(s);
- db.SaveChanges(); //將修改保存到數據庫中
- }
- }
- }
使用EF修改數據
先查詢出你要修改的那條數據,之后直接更改其中的值就可以了。
- class Program
- {
- static void Main(string[] args)
- {
- using (var db = new DBModel())
- {
- var student = db.students.FirstOrDefault(s => s.name == "蘿莉");
- student.age = 13; //將蘿莉的年齡改為13歲
- db.SaveChanges();
- }
- }
- }
使用EF刪除數據
使用EF刪除數據就和在List<>集合中刪除元素一樣
使用TransactionScope
- class Program
- {
- static void Main(string[] args)
- {
- using (var db = new DBModel())
- {
- var student = db.students.FirstOrDefault(s => s.name == "蘿莉"); //查找蘿莉
- db.students.Remove(student); //刪除蘿莉
- db.SaveChanges();
- }
- }
- }
在EF使用事務
事務就是確保一次數據庫操作,所有步驟都成功,如果哪一步出錯了,整個操作都將回滾。
在EF使用事務有兩種方案,一種是EF自帶的.BeginTransaction()方法,另一種是使用TransactionScope類。
使用.BeginTransaction()
使用.BeginTransaction()實現事務
- class Program
- {
- static void Main(string[] args)
- {
- using (var db = new DBModel())
- {
- var tran = db.Database.BeginTransaction(); //開啟事務
- try
- {
- var student = db.students.FirstOrDefault(s => s.name == "蘿莉");
- db.students.Remove(student); //刪除蘿莉
- db.SaveChanges();
- tran.Commit(); //必須調用Commit(),不然數據不會保存
- }
- catch (Exception ex)
- {
- tran.Rollback(); //出錯就回滾
- }
- }
- }
- }
使用TransactionScope類
使用之前記得引入System.Transactions.dll
使用TransactionScope
- class Program
- {
- static void Main(string[] args)
- {
- using (var db = new DBModel())
- {
- using (var tran = new TransactionScope()) //開啟事務
- {
- var student = db.students.FirstOrDefault(s => s.name == "蘿莉");
- db.students.Remove(student); //刪除蘿莉
- db.SaveChanges();
- tran.Complete(); //必須調用.Complete(),不然數據不會保存
- } //出了using代碼塊如果還沒調用Complete(),所有操作就會自動回滾
- }
- }
- }
兩種都可以,不過我覺得使用TransactionScope要方便一點。
到此使用EF6實現CRUD以及事務就介紹完了,下一節我們再來討論一下如何在EF執行SQL,以實現更加靈活的數據操作。