Entity Framework中執(zhí)行sql語句
一、為什么要在EF中執(zhí)行SQL語句
使用EF操作數(shù)據庫,可以避免寫SQL語句,完成使用Linq實現(xiàn),但為什么還要在EF中執(zhí)行SQL語句呢。如果要寫SQL語句,完全可以使用ADO.NET來操作數(shù)據庫。這樣說雖然沒錯,可是有些時候使用EF操作數(shù)據庫還是有一些不方便的地方,例如:如果要修改某一條記錄,按照EF的正常流程走,需要先把要修改的數(shù)據查詢出來,然后在去修改,這樣不僅麻煩而且性能也低,這時直接使用EF執(zhí)行SQL語句性能會提高很多。
而使用EF執(zhí)行SQL又比ADO.NET方便,特別是在執(zhí)行查詢語句的時候,EF會把查詢到的數(shù)據自動保存到數(shù)據實體中,省去了使用DataReader的麻煩。同時查詢出來的數(shù)據還會進行跟蹤,如果你修改了查詢出的值,之后就可以很方便的使用.SaveChanges()直接更新到數(shù)據庫了。
在數(shù)據上下文DbContext中有一個Database的屬性,Database屬性中有兩組方法:ExecuteSqlCommand()和SqlQuery()。這兩個方法都可以用來執(zhí)行SQL語句,但這兩個方法也有不同點:ExecuteSqlCommand()是不返回結果的,只返回受影響的行數(shù),所以ExecuteSqlCommand()更適合用來執(zhí)行創(chuàng)建、插入、更新、刪除操作(即執(zhí)行給定的DDL/DML命令)。SqlQuery()則會返回查詢到的結果,并將結果保存在數(shù)據實體中,所以SqlQuery()更適合執(zhí)行查詢操作。
二、使用ExecuteSqlCommand()執(zhí)行創(chuàng)建、插入、更新、刪除語句
ExecuteSqlCommand()的使用方法很簡單,直接傳入SQL語句就可以了,執(zhí)行完成后會返回受影響的行數(shù)。
在下面的例子中,entity是一個繼承自DbContext的對象。
1、執(zhí)行創(chuàng)建語句
// 執(zhí)行創(chuàng)建語句 string strCreateSQL = @"CREATE table test( id int primary key not null,name varchar(16),password varchar(20))"; // 注意:執(zhí)行create語句受影響的行數(shù)是-1 int result = entity.Database.ExecuteSqlCommand(strCreateSQL); if (result.Equals(-1)) { Console.WriteLine("創(chuàng)建成功!"); }
2、執(zhí)行Insert語句
// 執(zhí)行Insert語句 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語句
// 執(zhí)行Update語句 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語句
// 執(zhí)行刪除語句 string strDelSQL = "delete from test"; int result = entity.Database.ExecuteSqlCommand(strDelSQL); if (result > 0) { Console.WriteLine("刪除成功"); }
5、執(zhí)行Drop語句
string strDropSQL = "drop table test"; int result = entity.Database.ExecuteSqlCommand(strDropSQL); if (result.Equals(-1)) { Console.WriteLine("刪除成功"); }
注意:執(zhí)行DDL語句(create、alter、drop等)返回值是-1,DML(insert、update、delete)返回的是受影響的行數(shù)。
三、使用SqlQuery()查詢數(shù)據
SqlQuery()是用來執(zhí)行查詢的。SqlQuery()使用前需要指定返回值的類型。返回值類型可以是定義的實體類型,或者基元類型。例如:查詢一個用戶的完整信息,返回類型就是用戶實體類型;如果是統(tǒng)計有多少個用戶,返回值就是int類型。
注意:返回值的個數(shù)和名稱必須和傳入的類型中屬性個數(shù)、名稱相同,不如會報錯。
在下面的例子中User是根據數(shù)據庫表生成的實體類型。
string strSQL = "SELECT * FROM Users WHERE ID>=10 ORDER BY ID DESC"; var info = entity.Database.SqlQuery<User>(strSQL); foreach (var item in info) { Console.WriteLine("ID:" + item.ID + " " + "登錄名:" + item.LoginName + " " + "密碼:" + item.Password); }
運行結果:
前面說過返回值的個數(shù)和名稱必須和傳入的類型中屬性個數(shù)、名稱相同,不如會報錯。如果將SQL語句修改為只查詢ID、登錄名、密碼會出現(xiàn)下面的錯誤:
如果只想查詢ID、登錄名、密碼該怎么辦呢?那就需要單獨定義一個類(只包含ID、登錄名、密碼三個屬性)來保存數(shù)據.
新定義的類,只包含ID、登錄名、密碼三個屬性:
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<newUser>(strSQL); foreach (var item in info) { Console.WriteLine("ID:" + item.ID + " " + "登錄名:" + item.LoginName + " " + "密碼:" + item.Password); } } catch (Exception ex) { Console.WriteLine(ex.Message); }
運行結果:
返回值是基元類型:
查詢用戶數(shù)量,返回int類型
// 查詢用戶數(shù)量 string strSQL = "SELECT COUNT(*) FROM test"; var result = entity.Database.SqlQuery<int>(strSQL); // 注意:必須使用循環(huán)才會真正的去數(shù)據庫執(zhí)行SQL語句,否則不會再數(shù)據庫執(zhí)行SQL語句(EF的延遲加載) foreach(var item in result) { Console.WriteLine("用戶數(shù)量:" + item.ToString()); }
運行結果:
四、使用DbSet<T>下的SqlQuery()
在每個數(shù)據實體集合DbSet<T>下也有一個SqlQuery(),功能與上面介紹的一樣,只不過DbSet<T>下的SqlQuery()只能返回DbSet<T>中包含的類型,DbSet<T>下的SqlQuery()在返回數(shù)據的同時還會讓數(shù)據庫上下文(DBContext)跟蹤返回數(shù)據的狀態(tài),如果返回的數(shù)據發(fā)生了修改,就可以使用SaveChanges()將結果直接保存回數(shù)據庫。而Database.SqlQuery()查出的結果則不能跟蹤返回數(shù)據的狀態(tài)。
1、使用實體集合下面的SqlQuery()方法
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Users.SqlQuery(strSQL).FirstOrDefault(); user.Password = "測試實體下面的SqlQuery方法"; // 調用SaveChanges()方法可以更新Password字段 entity.SaveChanges();
2、使用Database下的SqlQuery()方法
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Database.SqlQuery<User>(strSQL).FirstOrDefault(); user.Password = "測試Database下面的SqlQuery方法"; // 調用SaveChanges()方法不可以更新Password字段 entity.SaveChanges();
如果希望使用Database下的SqlQuery()查詢出的數(shù)據在修改后也能保存到數(shù)據庫,可以使用下面的代碼:
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Database.SqlQuery<User>(strSQL).FirstOrDefault(); user.Password = "測試Database下面的SqlQuery方法"; // 設置這條數(shù)據的狀態(tài)是:Modified,這樣可以通知數(shù)據上下文,這條記錄也被修改了 entity.Entry<User>(user).State = System.Data.Entity.EntityState.Modified; // 調用SaveChanges()方法不可以更新Password字段 entity.SaveChanges();
到此這篇關于Entity Framework中執(zhí)行sql語句的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Entity?Framework使用Fluent?API配置案例
- Entity?Framework實現(xiàn)數(shù)據遷移
- Entity?Framework使用配置伙伴創(chuàng)建數(shù)據庫
- Entity Framework使用DbModelBuilder API創(chuàng)建表結構
- Entity Framework常用查詢語句
- Entity Framework系統(tǒng)架構與原理介紹
- Entity?Framework?Core實現(xiàn)Like查詢詳解
- Entity Framework Core批處理SQL語句
- Entity Framework Core實現(xiàn)軟刪除與查詢過濾器
- Entity Framework Core生成列并跟蹤列記錄
- Entity?Framework實體拆分多個表
相關文章
解決.net framework 4.0環(huán)境下遇到版本不同編譯不通過的方法詳解
本篇文章是對.net framework 4.0環(huán)境下遇到版本不同編譯不通過的解決方法進行了詳細的分析介紹,需要的朋友參考下2013-05-05SQL Server LocalDB 在 ASP.NET中的應用介紹
如同交響樂一樣,構造軟件系統(tǒng)不一定必須某個強大的明星驅動,我們站在歷代ADO.NET的肩膀上,更好地回歸到SQL Server的核心開發(fā):SQL Server LocalDB 在 ASP.NET中的應用2013-01-01ASP.NET Core Web App應用第三方Bootstrap模板的方法教程
這篇文章主要給大家介紹了關于ASP.NET Core Web App應用第三方Bootstrap模板的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起看看吧2018-06-06淺談ASP.NET Core 2.0 帶初始參數(shù)的中間件(譯)
這篇文章主要介紹了淺談ASP.NET Core 2.0 帶初始參數(shù)的中間件(譯),非常具有實用價值,需要的朋友可以參考下2017-10-10