網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、為什么要在EF中執(zhí)行SQL語(yǔ)句
使用EF操作數(shù)據(jù)庫(kù),可以避免寫SQL語(yǔ)句,完成使用Linq實(shí)現(xiàn),但為什么還要在EF中執(zhí)行SQL語(yǔ)句呢。如果要寫SQL語(yǔ)句,完全可以使用ADO.NET來操作數(shù)據(jù)庫(kù)。這樣說雖然沒錯(cuò),可是有些時(shí)候使用EF操作數(shù)據(jù)庫(kù)還是有一些不方便的地方,例如:如果要修改某一條記錄,按照EF的正常流程走,需要先把要修改的數(shù)據(jù)查詢出來,然后在去修改,這樣不僅麻煩而且性能也低,這時(shí)直接使用EF執(zhí)行SQL語(yǔ)句性能會(huì)提高很多。
而使用EF執(zhí)行SQL又比ADO.NET方便,特別是在執(zhí)行查詢語(yǔ)句的時(shí)候,EF會(huì)把查詢到的數(shù)據(jù)自動(dòng)保存到數(shù)據(jù)實(shí)體中,省去了使用DataReader的麻煩。同時(shí)查詢出來的數(shù)據(jù)還會(huì)進(jìn)行跟蹤,如果你修改了查詢出的值,之后就可以很方便的使用.SaveChanges()直接更新到數(shù)據(jù)庫(kù)了。
在數(shù)據(jù)上下文DbContext中有一個(gè)Database的屬性,Database屬性中有兩組方法:ExecuteSqlCommand()和SqlQuery()。這兩個(gè)方法都可以用來執(zhí)行SQL語(yǔ)句,但這兩個(gè)方法也有不同點(diǎn):ExecuteSqlCommand()是不返回結(jié)果的,只返回受影響的行數(shù),所以ExecuteSqlCommand()更適合用來執(zhí)行創(chuàng)建、插入、更新、刪除操作(即執(zhí)行給定的DDL/DML命令)。SqlQuery()則會(huì)返回查詢到的結(jié)果,并將結(jié)果保存在數(shù)據(jù)實(shí)體中,所以SqlQuery()更適合執(zhí)行查詢操作。
二、使用ExecuteSqlCommand()執(zhí)行創(chuàng)建、插入、更新、刪除語(yǔ)句
ExecuteSqlCommand()的使用方法很簡(jiǎn)單,直接傳入SQL語(yǔ)句就可以了,執(zhí)行完成后會(huì)返回受影響的行數(shù)。
在下面的例子中,entity是一個(gè)繼承自DbContext的對(duì)象。
1、執(zhí)行創(chuàng)建語(yǔ)句
// 執(zhí)行創(chuàng)建語(yǔ)句 string strCreateSQL = @"CREATE table test( id int primary key not null,name varchar(16),password varchar(20))"; // 注意:執(zhí)行create語(yǔ)句受影響的行數(shù)是-1 int result = entity.Database.ExecuteSqlCommand(strCreateSQL); if (result.Equals(-1)) { Console.WriteLine("創(chuàng)建成功!"); }
?2、執(zhí)行Insert語(yǔ)句
// 執(zhí)行Insert語(yǔ)句 string strInsertSQL = @"INSERT INTO test SELECT 1,'小明','1234' UNION SELECT 2,'小王','1234' UNION SELECT 3,'小紅','1234' "; int result = entity.Database.ExecuteSqlCommand(strInsertSQL); if (result > 0) { Console.WriteLine("插入成功"); }
3、執(zhí)行Update語(yǔ)句
// 執(zhí)行Update語(yǔ)句 string strUpdateSQL = @"UPDATE test SET password=@pwd1 WHERE id=@id1; UPDATE test SET password=@pwd2 WHERE id=@id2;"; SqlParameter[] para = { new SqlParameter("@pwd1","ceshi12we"), new SqlParameter("@id1",1), new SqlParameter("@pwd2","ceshi127890"), new SqlParameter("@id2",2), }; int result = entity.Database.ExecuteSqlCommand(strUpdateSQL, para); if (result > 0) { Console.WriteLine("更新成功"); }
4、執(zhí)行Delete語(yǔ)句
// 執(zhí)行刪除語(yǔ)句 string strDelSQL = "delete from test"; int result = entity.Database.ExecuteSqlCommand(strDelSQL); if (result > 0) { Console.WriteLine("刪除成功"); }
5、執(zhí)行Drop語(yǔ)句
string strDropSQL = "drop table test"; int result = entity.Database.ExecuteSqlCommand(strDropSQL); if (result.Equals(-1)) { Console.WriteLine("刪除成功"); }
注意:執(zhí)行DDL語(yǔ)句(create、alter、drop等)返回值是-1,DML(insert、update、delete)返回的是受影響的行數(shù)。
三、使用SqlQuery()查詢數(shù)據(jù)
SqlQuery()是用來執(zhí)行查詢的。SqlQuery()使用前需要指定返回值的類型。返回值類型可以是定義的實(shí)體類型,或者基元類型。例如:查詢一個(gè)用戶的完整信息,返回類型就是用戶實(shí)體類型;如果是統(tǒng)計(jì)有多少個(gè)用戶,返回值就是int類型。
注意:返回值的個(gè)數(shù)和名稱必須和傳入的類型中屬性個(gè)數(shù)、名稱相同,不如會(huì)報(bào)錯(cuò)。
在下面的例子中User是根據(jù)數(shù)據(jù)庫(kù)表生成的實(shí)體類型。
string strSQL = "SELECT * FROM Users WHERE ID>=10 ORDER BY ID DESC"; var info = entity.Database.SqlQuery(strSQL); foreach (var item in info) { Console.WriteLine("ID:" + item.ID + " " + "登錄名:" + item.LoginName + " " + "密碼:" + item.Password); }
運(yùn)行結(jié)果:
前面說過返回值的個(gè)數(shù)和名稱必須和傳入的類型中屬性個(gè)數(shù)、名稱相同,不如會(huì)報(bào)錯(cuò)。如果將SQL語(yǔ)句修改為只查詢ID、登錄名、密碼會(huì)出現(xiàn)下面的錯(cuò)誤:
如果只想查詢ID、登錄名、密碼該怎么辦呢?那就需要單獨(dú)定義一個(gè)類(只包含ID、登錄名、密碼三個(gè)屬性)來保存數(shù)據(jù).
新定義的類,只包含ID、登錄名、密碼三個(gè)屬性:
public class newUser { public int ID { get; set; } public string LoginName { get; set; } public string Password { get; set; } }
// 方法四:SqlQuery try { string strSQL = "SELECT ID,LoginName,Password FROM Users WHERE ID>=10 ORDER BY ID DESC"; var info = entity.Database.SqlQuery(strSQL); foreach (var item in info) { Console.WriteLine("ID:" + item.ID + " " + "登錄名:" + item.LoginName + " " + "密碼:" + item.Password); } } catch (Exception ex) { Console.WriteLine(ex.Message); }
運(yùn)行結(jié)果:
返回值是基元類型:
查詢用戶數(shù)量,返回int類型
// 查詢用戶數(shù)量 string strSQL = "SELECT COUNT(*) FROM test"; var result = entity.Database.SqlQuery(strSQL); // 注意:必須使用循環(huán)才會(huì)真正的去數(shù)據(jù)庫(kù)執(zhí)行SQL語(yǔ)句,否則不會(huì)再數(shù)據(jù)庫(kù)執(zhí)行SQL語(yǔ)句(EF的延遲加載) foreach(var item in result) { Console.WriteLine("用戶數(shù)量:" + item.ToString()); }
運(yùn)行結(jié)果:
四、使用DbSet下的SqlQuery()
在每個(gè)數(shù)據(jù)實(shí)體集合DbSet
1、使用實(shí)體集合下面的SqlQuery()方法
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Users.SqlQuery(strSQL).FirstOrDefault(); user.Password = "測(cè)試實(shí)體下面的SqlQuery方法"; // 調(diào)用SaveChanges()方法可以更新Password字段 entity.SaveChanges();
2、使用Database下的SqlQuery()方法
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Database.SqlQuery(strSQL).FirstOrDefault(); user.Password = "測(cè)試Database下面的SqlQuery方法"; // 調(diào)用SaveChanges()方法不可以更新Password字段 entity.SaveChanges();
如果希望使用Database下的SqlQuery()查詢出的數(shù)據(jù)在修改后也能保存到數(shù)據(jù)庫(kù),可以使用下面的代碼:
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Database.SqlQuery(strSQL).FirstOrDefault(); user.Password = "測(cè)試Database下面的SqlQuery方法"; // 設(shè)置這條數(shù)據(jù)的狀態(tài)是:Modified,這樣可以通知數(shù)據(jù)上下文,這條記錄也被修改了 entity.Entry (user).State = System.Data.Entity.EntityState.Modified; // 調(diào)用SaveChanges()方法不可以更新Password字段 entity.SaveChanges();
原文鏈接:https://www.cnblogs.com/dotnet261010/p/7249153.html
相關(guān)推薦
- 2022-07-01 Python?Pandas中合并數(shù)據(jù)的5個(gè)函數(shù)使用詳解_python
- 2022-06-02 C語(yǔ)言深入淺出解析二叉樹_C 語(yǔ)言
- 2022-05-02 分布式利器redis及redisson的延遲隊(duì)列實(shí)踐_Redis
- 2024-02-26 IDEA隱藏指定文件/文件夾
- 2022-07-23 C#線程間通信的異步機(jī)制_C#教程
- 2022-03-06 Android系統(tǒng)服務(wù)概覽_Android
- 2022-07-06 C語(yǔ)言中#pragma?once的作用_C 語(yǔ)言
- 2022-05-25 Springboot使用Redis-Cell實(shí)現(xiàn)限流
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支