網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Entity?Framework?Core中執(zhí)行SQL語(yǔ)句和存儲(chǔ)過(guò)程的方法介紹_實(shí)用技巧
作者:Sweet-Tang ? 更新時(shí)間: 2022-04-25 編程語(yǔ)言無(wú)論ORM有多么強(qiáng)大,總會(huì)出現(xiàn)一些特殊的情況,它無(wú)法滿足我們的要求。在這篇文章中,我們介紹幾種執(zhí)行SQL的方法。
表結(jié)構(gòu)
在具體內(nèi)容開(kāi)始之前,我們先簡(jiǎn)單說(shuō)明一下要使用的表結(jié)構(gòu)。
public class Category { public int CategoryID { get; set; } public string CategoryName { get; set; } }
在Category
定義了兩個(gè)字段:CategoryID
、CategoryName
。
public class SampleDbContext : DbContext { public virtual DbSetCategories { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var sqlConnectionStringBuilder = new SqlConnectionStringBuilder { DataSource = "10.0.1.5", InitialCatalog = "TestDataBase", UserID = "sa", Password = "******" }; optionsBuilder.UseSqlServer(sqlConnectionStringBuilder.ConnectionString); base.OnConfiguring(optionsBuilder); } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); EntityTypeBuilder entityTypeBuilder = modelBuilder.Entity (); entityTypeBuilder.ToTable("Category"); entityTypeBuilder.HasKey(e => e.CategoryID); entityTypeBuilder.Property(e => e.CategoryID).UseSqlServerIdentityColumn(); } }
我們使用SampleDbContext
來(lái)訪問(wèn)數(shù)據(jù)庫(kù)。
FromSql執(zhí)行SQL語(yǔ)句
Entity Framework Core為DbSet
提供了一個(gè)擴(kuò)展方法FromSql
,用于執(zhí)行SQL語(yǔ)句或存儲(chǔ)過(guò)程,以下示例使用FromSql
加載所有的數(shù)據(jù)。
using (var dataContext = new SampleDbContext()) { var query = dataContext.Categories.FromSql("select * from Category"); var result = query.ToList(); }
對(duì)于帶有參數(shù)的SQL語(yǔ)句,我們使用C# 6 語(yǔ)法將SQL寫(xiě)成如下:
using (var dataContext = new SampleDbContext()) { var categoryID = 1; var query = dataContext.Categories.FromSql($"select * from Category where CategoryID={categoryID}"); var result = query.ToList(); }
注意:這里不是直接使用拼接的方式處理SQL,而是轉(zhuǎn)化為參數(shù)化的SQL語(yǔ)句,這有助于防止SQL注入攻擊。我們可以使用SQL Server Profiler幫我們驗(yàn)證:
exec sp_executesql N'select * from Category where CategoryID=@p0 ',N'@p0 int',@p0=1
如果您不使用C# 6的語(yǔ)法特征,我們必須使用 @p0、@p1 ... @pn 做為SQL語(yǔ)句的參數(shù):
using (var dataContext = new SampleDbContext()) { var categoryID = 1; var categoryName = "Product"; var query = dataContext.Categories.FromSql("select * from Category where CategoryID=@p0 and CategoryName=@p1" categoryID, categoryName); var result = query.ToList(); Assert.NotNull(result); }
在上述SQL語(yǔ)句中中,將@p0
映射到categoryID
、@ p1
映射到categoryName
。
FromSql
擴(kuò)展方法返回的是IQueryable
對(duì)象,要們還可以接著使用一些Linq的方法,示例如下:
using (var dataContext = new SampleDbContext()) { var categoryID = 1; var query = dataContext.Categories.FromSql("select * from Category") .Where(item => item.CategoryID == categoryID) .OrderBy(item => item.CategoryName); var result = query.ToList(); }
不過(guò)在這里,使用的是子查詢,使用SQL Server Profiler捕獲到的SQL語(yǔ)句如下:
exec sp_executesql N'SELECT [item].[CategoryID], [item].[CategoryName] FROM ( select * from Category ) AS [item] WHERE [item].[CategoryID] = @__categoryID_1 ORDER BY [item].[CategoryName]',N'@__categoryID_1 int',@__categoryID_1=1
提示:使用
FromSql
時(shí),需要在執(zhí)行的SQL語(yǔ)句中返回所有列,并且列名必須與實(shí)體屬性名相匹配,否則執(zhí)行會(huì)出錯(cuò)。
FromSql執(zhí)行存儲(chǔ)過(guò)程
存儲(chǔ)過(guò)程與SQL語(yǔ)句寫(xiě)法基本一致,使用存儲(chǔ)過(guò)程的示例如下:
using (var dataContext = new SampleDbContext()) { var categoryID = 1; var query = dataContext.Categories.FromSql($"GetCategoryById {categoryID}"); var result = query.ToList(); Assert.NotNull(result); }
這些參數(shù)的順序必須與存儲(chǔ)過(guò)程參數(shù)的順序一致。
提示:使用
FromSql
執(zhí)行存儲(chǔ)過(guò)程時(shí),如果使用'Where'、'OrderBy'等Linq語(yǔ)法,這些操作不會(huì)生成SQL語(yǔ)句,而是在.Net中對(duì)存儲(chǔ)過(guò)程返回的集合進(jìn)行過(guò)濾與排序。
ExecuteSqlCommand
在DbContext
暴露了一個(gè)Database
屬性,它包括一個(gè)ExecuteSqlCommand
方法。此方法返回一個(gè)整數(shù),表示執(zhí)行的SQL語(yǔ)句影響的行數(shù)。有效的操作是INSERT
、UPDATE
和DELETE
,不能用于返回實(shí)體。
using (var dataContext = new SampleDbContext()) { var categoryID = 1; var categoryName = "Product"; var result = dataContext.Database.ExecuteSqlCommand($"UPDATE dbo.Category SET CategoryName={categoryName} WHERE CategoryID={categoryID}"); }
總結(jié)
原文鏈接:https://www.cnblogs.com/tdfblog/p/execute-sql-stored-procedure-in-entity-framework-core.html
相關(guān)推薦
- 2023-06-19 scrapy?遠(yuǎn)程登錄控制臺(tái)的實(shí)現(xiàn)_python
- 2022-08-15 前端el-select下拉數(shù)據(jù)太長(zhǎng)顯示...鼠標(biāo)浮上去顯示全部
- 2023-02-02 一文帶你深入了解C++中的類(lèi)型轉(zhuǎn)換_C 語(yǔ)言
- 2022-04-24 Postman設(shè)置環(huán)境變量的實(shí)現(xiàn)示例_相關(guān)技巧
- 2022-05-20 ASP.NET?MVC項(xiàng)目部署方式介紹_基礎(chǔ)應(yīng)用
- 2022-12-01 Docker系列學(xué)習(xí)之Swarm?mode管理節(jié)點(diǎn)常用命令詳解_docker
- 2023-03-04 Google大佬都用的廣播goAsync源碼分析_Android
- 2022-04-02 Pandas實(shí)現(xiàn)groupby分組統(tǒng)計(jì)的實(shí)踐_python
- 最近更新
-
- 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)證過(guò)濾器
- Spring Security概述快速入門(mén)
- 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)程分支