日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL via EF6 的试用报告

發(fā)布時(shí)間:2023/12/10 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL via EF6 的试用报告 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

MySQL via EF6 的試用報(bào)告
1、如何通過 EF6 來連接 MySQL?
2、如何通過 EF6 來實(shí)現(xiàn) CRUD?
2.1、Create 添加
2.2、Retrieve 查詢
2.3、Update 修改
2.4、Delete 刪除
3、如何更好的運(yùn)用 EF6 來完成工作?
3.1、傳說中 EF 的三種模式
3.2、EF6 執(zhí)行原生 SQL 查詢
3.3、EF6 執(zhí)行原生 SQL 增刪改
3.4、EF6 不推薦的 CRUD 寫法
3.5、EF6 性能優(yōu)化
3.6、EF6 開發(fā)及調(diào)試技巧
4、總結(jié)
4.1、MySQL 官方組件的用途說明
4.2、本文 Demo 的代碼補(bǔ)充說明
公司的項(xiàng)目中用的 ORM 是 Dapper,代碼中充斥著大量的 SQL 語句,為了少寫 SQL 語句,領(lǐng)導(dǎo)讓我把 EF6 也加進(jìn)去看會(huì)不會(huì)有問題。按照指示,我在新的代碼分支引入了 EF6 并做了 CRUD 的測試,結(jié)論是混合使用 Dapper 和 EF6 沒問題。為了讓團(tuán)隊(duì)中沒用過 EF 的同事也能快速上手 EF,我把我的試用記錄重新整理了一下,于是乎就有了本文。

1、如何通過 EF6 來連接 MySQL?
1、安裝 MySQL 的 .NET 驅(qū)動(dòng)

要在 .NET 項(xiàng)目中連接 MySQL 首先得安裝 MySQL 的 .NET 驅(qū)動(dòng)。這個(gè)驅(qū)動(dòng)是向下兼容的,官方下載地址:MySQL Connector/NET。

2、安裝 MySql.Data.EntityFramework

Install-Package MySql.Data.EntityFramework -Version 8.0.15
上面的 NuGet 命令會(huì)自動(dòng)幫你把 EF6 和 MySql.Data 都安裝好,無需額外再安裝。

3、創(chuàng)建模型類

有了和數(shù)據(jù)庫中表對應(yīng)的模型類,才能方便的操作數(shù)據(jù)庫而不必寫 SQL 語句。如定義一個(gè) Person 實(shí)體,示例如下:

[Table("person")] // 這里不僅可以自定義表的 Name 還可以自定義表的 Schema
public class Person {

[Key] public Int32 ID { get; set; } public String Name { get; set; } public DateTime Birthday { get; set; } public Int32 NationID { get; set; } public Nation Nation { get; set; }

}
定義實(shí)體的注意事項(xiàng):

1、模型類名與表名不必相同。如果不同,則需要用 TableAttribute 標(biāo)注一下;如果相同,則可以省略該 Attribute。
2、主鍵名不必非得是 ID。如果不是,則需要用 KeyAttribute 標(biāo)注一下;如果是 ID,則可以省略該 Attribute。EF 遵循“約定大于配置”的開發(fā)原則,比如 EF 中主鍵名默認(rèn)為 ID 就是 EF 的一個(gè)內(nèi)置約定,EF 還支持自定義約定。
4、創(chuàng)建數(shù)據(jù)庫上下文類

有了數(shù)據(jù)庫上下文,就可以連接數(shù)據(jù)庫了,然后在上下文中定義相應(yīng)的 DbSet(實(shí)體對象集合),就能直接對數(shù)據(jù)庫進(jìn)行 CRUD 操作了。如創(chuàng)建一個(gè) Demo 的上下文,示例如下:

public class DemoDbContext : DbContext {

// 聲明 DbSet,實(shí)現(xiàn) CRUD 的方法定義在 DbSet 中 public DbSet<Person> Persons { get; set; } public DbSet<Nation> Nations { get; set; }public DemoDbContext() : base("name=ConnectionString") {// 關(guān)閉遷移,EF Code First 默認(rèn)會(huì)在 Model 發(fā)生改變后自動(dòng)更新數(shù)據(jù)庫Database.SetInitializer<DemoDbContext>(null); }protected override void OnModelCreating(DbModelBuilder modelBuilder) {base.OnModelCreating(modelBuilder);// 解決表名變復(fù)數(shù)的問題,EF 生成 SQL 語句時(shí)默認(rèn)會(huì)將實(shí)體名變成復(fù)數(shù)modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); }

}
定義上下文的注意事項(xiàng):

1、創(chuàng)建的數(shù)據(jù)庫上下文類必須繼承 DbContext 類。
2、在上下文類的構(gòu)造函數(shù)中通過 base 的方式指定數(shù)據(jù)庫連接字符串。base 的參數(shù)寫法有多種,常見的寫法如下:
base("ConnectionString")
base("name=ConnectionString")
base(new MySqlConnection("..."), false)
3、由于 EF 的遷移功能過于復(fù)雜,且非必要,一般不用,在構(gòu)造函數(shù)中關(guān)閉即可。
4、EF 默認(rèn)生成的表名是 Model 名的復(fù)數(shù),可在 OnModelCreating 中移除該轉(zhuǎn)換規(guī)則。
2、如何通過 EF6 來實(shí)現(xiàn) CRUD?
2.1、Create 添加
1、向一個(gè)表中添加一條數(shù)據(jù),示例如下:
using (var context = new DemoDbContext()) {

var p = new Person() { Name = "Andy", Gender = 1 }; context.Persons.Add(p); context.SaveChanges(); // 返回受影響行數(shù) 1

}
上面的代碼會(huì)生成 1 條 INSERT 語句和 1 條 SELECT 語句。

2、同時(shí)向存在主外鍵的兩個(gè)表中添加一條數(shù)據(jù),示例如下:
using (var context = new DemoDbContext()) {

var n = new Nation() { Name = "China" }; var p = new Person() { Name = "Mark", Gender = 1, NationID = n.ID }; context.Nations.Add(n); context.Persons.Add(p); context.SaveChanges(); // 返回受影響行數(shù) 2

}
上面的代碼會(huì)生成 1 條 INSERT 語句和 2 條 SELECT 語句。

3、一次添加多個(gè)并附加事務(wù):
String connectionString = "server=localhost;port=3306;database=demo;uid=root;pwd=";
using (MySqlConnection connection = new MySqlConnection(connectionString)) {

connection.Open(); MySqlTransaction transaction = connection.BeginTransaction();try {using(var context = new DemoDbContext(connection)) {context.Database.UseTransaction(transaction);List<Person> ps = new List<Person>();ps.Add(new Person { Name = "Mark", Gender = 1 });ps.Add(new Person { Name = "Jack", Gender = 1 });ps.Add(new Person { Name = "Tom", Gender = 1 });context.Persons.AddRange(ps);context.SaveChanges();}transaction.Commit(); } catch {transaction.Rollback();throw; }

}
2.2、Retrieve 查詢
1、EF 查詢支持 LINQ 寫法,必須在最后調(diào)用ToList()才會(huì)執(zhí)行查詢,示例如下:
using (var context = new DemoDbContext()) {

context.Database.Log = Console.WriteLine; var list1 = (from p in context.Persons where p.ID == 1 select p).ToList(); var list2 = (from p in context.Persons select p.Name).ToList(); var query = from p in context.Persons select p; query = from p in query where p.ID >= 1 select p; query = from p in query where p.NationID == 1 select p; query = from p in query orderby p.Name descending select p; query.ToList();

}
2、EF 查詢支持 Lambda 寫法,示例如下:
using (var context = new DemoDbContext()) {

context.Database.Log = Console.WriteLine; // LIMIT 1 var p1 = context.Persons.FirstOrDefault(); // LIMIT 2,不會(huì)做參數(shù)化處理 var p2 = context.Persons.Single(p => p.ID == 5); // LIMIT 2,會(huì)自動(dòng)做參數(shù)化處理 var p3 = context.Persons.Find(3); // 會(huì)自動(dòng)做參數(shù)化處理 var p4 = context.Persons.Where(p => p.Name.Contains("Andy")).ToList(); // 只查詢部分?jǐn)?shù)據(jù)行,可用這個(gè)實(shí)現(xiàn)分頁查詢 var p5 = context.Persons.OrderBy(p => p.Name).Skip(3).Take(5).ToList(); // 帶條件的分頁查詢 var p6 = context.Persons.Where(p => p.ID > 0).OrderBy(p => p.Name).Skip(3).Take(5).ToList();

}
3、查詢關(guān)聯(lián)數(shù)據(jù),示例如下:
using (var context = new DemoDbContext()) {

var persons = context.Persons.Include(p => p.Nation).ToList();

}
上面的代碼會(huì)生成 1 條內(nèi)連接 SELECT 語句。

2.3、Update 修改
1、修改一條確定存在的數(shù)據(jù)時(shí),用如下語句:
using (var context = new DemoDbContext()) {

var p = new Person() { ID = 3, Name = "Andy" }; context.Persons.Attach(p); context.Entry(p).Property(i => i.Name).IsModified = true; context.SaveChanges(); // 返回受影響行數(shù)

}
上面的代碼會(huì)生成 1 條 UPDATE 語句,數(shù)據(jù)不存在時(shí)會(huì)報(bào)錯(cuò)。

2、如果需要確認(rèn)數(shù)據(jù)存在后再修改的話,用如下語句:
using (var context = new DemoDbContext()) {

var p = context.Persons.Find(1); // 也可以用 FirstOrDefault 或其它查詢方法 if (p != null) {p.Name = "Peter";context.Persons.Attach(p);context.Entry(p).Property(i => i.Name).IsModified = true; // 指定更新字段context.SaveChanges(); // 返回受影響行數(shù) }

}
上面的代碼會(huì)生成 1 條 UPDATE 語句和 1 條 SELECT 語句。

2.4、Delete 刪除
1、刪除一條確定存在的數(shù)據(jù)時(shí),用如下語句:
using (var context = new DemoDbContext()) {

var p = new Person() { ID = 1 }; context.Persons.Attach(p); context.Persons.Remove(p); context.SaveChanges(); // 返回受影響行數(shù)

}
上面的代碼會(huì)生成 1 條 DELETE 語句,數(shù)據(jù)不存在時(shí)會(huì)報(bào)錯(cuò)。

2、如果需要確認(rèn)數(shù)據(jù)存在后再刪除的話,用如下語句:
using (var context = new DemoDbContext()) {

var p = context.Persons.FirstOrDefault(it => it.ID == 1); if (p != null) {context.Persons.Attach(p);context.Persons.Remove(p);context.SaveChanges(); }

}
3、如何更好的運(yùn)用 EF6 來完成工作?
技術(shù)好的人經(jīng)常講業(yè)務(wù)場景,相反,有些技術(shù)差的人卻喜歡不由分說的吐槽那些他根本就沒搞懂的技術(shù)。在 .NET 圈子里,有人對 EF 是愛不釋手,也有人對 EF 是各種吐槽。

我很喜歡的一句話是:“沒有不好的技術(shù),只有沒被用好的技術(shù)”,我的理解是任何技術(shù)都有局限性,作為程序員,我們要做的是結(jié)合實(shí)際業(yè)務(wù)場景來選用最合適的技術(shù)。要想在項(xiàng)目中更好的運(yùn)用 EF,就得更多的了解 EF 技術(shù),本節(jié)就來分享一下我試用 EF6 過程中的一些收獲。

3.1、傳說中 EF 的三種模式
為什么說 EF 的三種模式是傳說呢?因?yàn)樾掳娴?EF 默認(rèn)只支持 Code First 這一種模式了。要想用 Database First 或 Model First 還得把 Visual Studio 降級到 VS10 或 VS12 才行,實(shí)在沒必要,下面簡單羅列下每種模式的特點(diǎn):

1、Database First:即數(shù)據(jù)庫優(yōu)先,先創(chuàng)建好數(shù)據(jù)庫和表,然后自動(dòng)生成 EDM(實(shí)體數(shù)據(jù)模型)文件,再由 EDM 文件生成模型類。當(dāng)現(xiàn)有數(shù)據(jù)庫結(jié)構(gòu)比較成熟穩(wěn)定時(shí),可用這種模式實(shí)現(xiàn)快速開發(fā)。
2、Model First:即模型優(yōu)先,先創(chuàng)建可視化的 EDM 文件,然后由 EDM 文件來自動(dòng)生成模型類和數(shù)據(jù)庫。開發(fā)速度快,但代碼冗余。寫個(gè)小 Demo 還行,但企業(yè)級開發(fā)一般沒人用這個(gè)模式。
3、Code First:即代碼優(yōu)先,先寫好模型類,然后自動(dòng)生成數(shù)據(jù)庫,沒有 EDM 文件。代碼簡潔可控,也是官方和業(yè)界首推的模式。
3.2、EF6 執(zhí)行原生 SQL 查詢
總會(huì)有些時(shí)候,我們?yōu)榱诵阅芑蛘咂渌鞣N各樣的緣故,而不得不寫 SQL 語句,EF 提供了直接執(zhí)行 SQL 語句的方法SqlQuery()。

1、執(zhí)行無參數(shù)的原生 SQL 查詢,示例如下:
using (var context = new DemoDbContext()) {

var persons = context.Persons.SqlQuery("SELECT * FROM Person").ToList();

}
2、執(zhí)行帶參數(shù)的原生 SQL 查詢,示例如下:
using (var context = new DemoDbContext()) {

var sql = "SELECT t.* FROM Person t WHERE t.Gender=@Gender"; var p1 = context.Persons.SqlQuery(sql, new MySqlParameter("@Gender", 1)).ToList(); // 下面這種更簡單的寫法相當(dāng)于上面兩句,EF 會(huì)自動(dòng)將其轉(zhuǎn)換為參數(shù)化查詢 var p2 = context.Persons.SqlQuery("SELECT t.* FROM Person t WHERE t.Gender={0}", 1).ToList();

}
3、只查詢部分可選字段,示例如下:
using (var context = new DemoDbContext()) {

var persons = context.Database.SqlQuery<MiniPerson>("SELECT t.ID,t.Name FROM Person t").ToList();

}
注意:這里用的是MiniPerson類,而不是模型類Persons,因?yàn)橛媚P皖悤r(shí),查詢返回的字段必須與其模型中的字段對應(yīng),而用非模型類時(shí)則沒有這個(gè)限制,EF 會(huì)自動(dòng)把值賦給相應(yīng)的字段,并忽略其它字段,即便完全不匹配也不會(huì)報(bào)錯(cuò)。

4、統(tǒng)計(jì)表中的數(shù)據(jù)條數(shù),示例如下:
using (var context = new DemoDbContext()) {

var count = context.Database.SqlQuery<Int32>("SELECT COUNT(1) FROM Person").SingleOrDefault();

}
其實(shí) EF 的SqlQuery()還支持調(diào)用存儲過程,但實(shí)際開發(fā)中,一般最好不要存儲過程。因?yàn)橐坏┯昧舜鎯^程,相比較得到的性能提升,往往付出的維護(hù)代價(jià)會(huì)更大,得不償失。

3.3、EF6 執(zhí)行原生 SQL 增刪改
EF6 調(diào)用增刪改等命令語句的方法是ExecuteSqlCommand(),示例如下:

using (var context = new DemoDbContext()) {

context.Database.ExecuteSqlCommand("INSERT INTO Person VALUES(DEFAULT,'小明',NOW(),1)"); context.Database.ExecuteSqlCommand("UPDATE Person SET Name='小王' WHERE ID=8"); context.Database.ExecuteSqlCommand("DELETE FROM Person WHERE ID=14");

}
一般用 EF 就是為了不寫 SQL 語句,尤其是大多數(shù)時(shí)候不會(huì)造成性能問題的增刪改語句,所以使用ExecuteSqlCommand()的概率是比較低的。

3.4、EF6 不推薦的 CRUD 寫法
有些朋友通過別人的帖子發(fā)現(xiàn)直接更改實(shí)體狀態(tài)也能修改數(shù)據(jù),然后就一直這么用。但如果你不是很了解 EF 的實(shí)體狀態(tài)管理機(jī)制,就很可能會(huì)給自己挖坑,所以一般不推薦這種 CRUD 的寫法。

我多次看到網(wǎng)上有人問諸如 EF 改了數(shù)據(jù)保存報(bào)錯(cuò)之類的問題,基本都是他自己還沒搞清楚 EF 各個(gè)實(shí)體狀態(tài)的含義,然后就在那兒強(qiáng)制更改實(shí)體狀態(tài),然后遇到坑自己還解決不了。這種做法有可能還會(huì)破壞 EF 的樂觀并發(fā)控制,而且有些版本也不支持這種做法。下面給出兩個(gè)負(fù)面案例:

1、不推薦的修改寫法,會(huì)更新所有字段,示例如下:
using (var context = new DemoDbContext()) {

context.Database.Log = Console.WriteLine; var p = new Person() { ID = 3, Name = "Andy" }; context.Entry(p).State = EntityState.Modified; context.SaveChanges(); // 返回受影響行數(shù) 1

}
上面的代碼會(huì)生成 1 條 UPDATE 語句。

2、不推薦的刪除寫法,示例如下:
using (var context = new DemoDbContext()) {

var p = new Person() { ID = 1 }; context.Entry(p).State = EntityState.Deleted; context.SaveChanges(); // 返回受影響行數(shù) 1

}
上面的代碼會(huì)生成 1 條 DELETE 語句。

3.5、EF6 性能優(yōu)化
1、非跟蹤查詢 AsNoTracking
默認(rèn)情況下,EF 會(huì)一直跟蹤實(shí)體的狀態(tài),這也是為什么當(dāng)我們調(diào)用SaveChanges()的時(shí)候,EF 能夠把最終的數(shù)據(jù)狀態(tài)準(zhǔn)確提交到數(shù)據(jù)庫的原因。但有些時(shí)候,我們查詢出數(shù)據(jù)只是為了做展示,并不需要修改或刪除,這時(shí)候就可以調(diào)用AsNoTracking()來使得對象為 Detached 狀態(tài),之后 EF 就不再跟蹤這個(gè)對象狀態(tài)了,在合適的場景下能顯著提升性能。
using (var context = new DemoDbContext()) {

// 查詢所有人并且不跟蹤他們的狀態(tài) var p1 = context.Persons.AsNoTracking().ToList(); // 查詢部分人并且不跟蹤他們的狀態(tài) var p2 = context.Persons.Where(i => i.NationID == 1).AsNoTracking().ToList();

}
2、EF 默認(rèn)是開啟了 LoayLazy 的,別手賤關(guān)了就行。如下是默認(rèn)配置:
this.Configuration.ProxyCreationEnabled = true;
this.Configuration.LazyLoadingEnabled = true;
3.6、EF6 開發(fā)及調(diào)試技巧
1、如果想知道 EF 會(huì)執(zhí)行什么 SQL 語句,比如是控制臺項(xiàng)目,在執(zhí)行代碼塊中增加如下語句即可:
context.Database.Log = Console.WriteLine;
2、如果是自己測試,可以讓 EF 每次都根據(jù)代碼更新數(shù)據(jù)庫,在上下文構(gòu)造函數(shù)中增加如下代碼即可:
// 當(dāng)數(shù)據(jù)庫模型發(fā)生改變時(shí),則刪除當(dāng)前數(shù)據(jù)庫,重建新的數(shù)據(jù)庫(實(shí)際開發(fā)中永遠(yuǎn)不要這么寫,太危險(xiǎn)了)
Database.SetInitializer(new DropCreateDatabaseIfModelChanges());
或者在 CRUD 代碼塊中加入如下代碼,僅當(dāng)數(shù)據(jù)庫不存在時(shí),才由 EF 創(chuàng)建數(shù)據(jù)庫:

context.Database.CreateIfNotExists();
4、總結(jié)
本文主要講解了如何快速上手 EF6 和基本的 CRUD 操作。用 .NET 技術(shù)的博友都知道,如今 .NET 陣營除了經(jīng)典的 .NET Framework 之外,還有一個(gè)開源版的 .NET Core。對應(yīng)的,EF 也適時(shí)地推出了 EF Core 版,如果你的項(xiàng)目是 .NET 的,那就繼續(xù)用 EF6 吧,畢竟是久經(jīng)考驗(yàn)的版本,而 EF Core 是全新開發(fā)的,更適合 .NET Core 類型的項(xiàng)目。而且官方也說從 EF6 到 EF Core 是移植而不是升級。

4.1、MySQL 官方組件的用途說明
1、mysql-connector-net:MySQL Connector/NET 是 MySQL 官方的 .NET 驅(qū)動(dòng)程序,或者說是 MySQL for .NET 的客戶端開發(fā)包,其中包含了 .NET 連接 MySQL 所必須的 dll 文件。
2、mysql-for-visualstudio:6.7 以下版本的驅(qū)動(dòng)中會(huì)包含該組件,它的作用是在通過 VS 建立實(shí)體模型時(shí),在數(shù)據(jù)源中增加 MySQL 類型選項(xiàng)。如果只用 Code First,那么就不需要該組件了。
3、mysql-connector-odbc:MySQL Connector/ODBC 使得用戶可以通過 ODBC(Open Database Connectivity,開放數(shù)據(jù)庫互聯(lián))來連接 MySQL 服務(wù)器。
4.2、本文 Demo 的代碼補(bǔ)充說明
文中的 Nation 實(shí)體定義如下:
public class Nation {

public Int32 ID { get; set; } public String Name{ get; set; }

}
文中的 MiniPerson 類定義如下:
public class MiniPerson {

public Int32 ID { get; set; } public String Name { get; set; }

}
本文鏈接:http://www.cnblogs.com/hanzongze/p/ef6-trial-report.html
版權(quán)聲明:本文為博客園博主 韓宗澤 原創(chuàng)

總結(jié)

以上是生活随笔為你收集整理的MySQL via EF6 的试用报告的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。