<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
使用EF運算元據庫,可以避免寫SQL語句,完成使用Linq實現,但為什麼還要在EF中執行SQL語句呢。如果要寫SQL語句,完全可以使用ADO.NET來運算元據庫。這樣說雖然沒錯,可是有些時候使用EF運算元據庫還是有一些不方便的地方,例如:如果要修改某一條記錄,按照EF的正常流程走,需要先把要修改的資料查詢出來,然後在去修改,這樣不僅麻煩而且效能也低,這時直接使用EF執行SQL語句效能會提高很多。
而使用EF執行SQL又比ADO.NET方便,特別是在執行查詢語句的時候,EF會把查詢到的資料自動儲存到資料實體中,省去了使用DataReader的麻煩。同時查詢出來的資料還會進行跟蹤,如果你修改了查詢出的值,之後就可以很方便的使用.SaveChanges()直接更新到資料庫了。
在資料上下文DbContext中有一個Database的屬性,Database屬性中有兩組方法:ExecuteSqlCommand()和SqlQuery()。這兩個方法都可以用來執行SQL語句,但這兩個方法也有不同點:ExecuteSqlCommand()是不返回結果的,只返回受影響的行數,所以ExecuteSqlCommand()更適合用來執行建立、插入、更新、刪除操作(即執行給定的DDL/DML命令)。SqlQuery()則會返回查詢到的結果,並將結果儲存在資料實體中,所以SqlQuery()更適合執行查詢操作。
ExecuteSqlCommand()的使用方法很簡單,直接傳入SQL語句就可以了,執行完成後會返回受影響的行數。
在下面的例子中,entity是一個繼承自DbContext的物件。
// 執行建立語句 string strCreateSQL = @"CREATE table test( id int primary key not null,name varchar(16),password varchar(20))"; // 注意:執行create語句受影響的行數是-1 int result = entity.Database.ExecuteSqlCommand(strCreateSQL); if (result.Equals(-1)) { Console.WriteLine("建立成功!"); }
// 執行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("插入成功"); }
// 執行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("更新成功"); }
// 執行刪除語句 string strDelSQL = "delete from test"; int result = entity.Database.ExecuteSqlCommand(strDelSQL); if (result > 0) { Console.WriteLine("刪除成功"); }
string strDropSQL = "drop table test"; int result = entity.Database.ExecuteSqlCommand(strDropSQL); if (result.Equals(-1)) { Console.WriteLine("刪除成功"); }
注意:執行DDL語句(create、alter、drop等)返回值是-1,DML(insert、update、delete)返回的是受影響的行數。
SqlQuery()是用來執行查詢的。SqlQuery()使用前需要指定返回值的型別。返回值型別可以是定義的實體型別,或者基元型別。例如:查詢一個使用者的完整資訊,返回型別就是使用者實體型別;如果是統計有多少個使用者,返回值就是int型別。
注意:返回值的個數和名稱必須和傳入的型別中屬性個數、名稱相同,不如會報錯。
在下面的例子中User是根據資料庫表生成的實體型別。
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); }
執行結果:
前面說過返回值的個數和名稱必須和傳入的型別中屬性個數、名稱相同,不如會報錯。如果將SQL語句修改為只查詢ID、登入名、密碼會出現下面的錯誤:
如果只想查詢ID、登入名、密碼該怎麼辦呢?那就需要單獨定義一個類(只包含ID、登入名、密碼三個屬性)來儲存資料.
新定義的類,只包含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); }
執行結果:
返回值是基元型別:
查詢使用者數量,返回int型別
// 查詢使用者數量 string strSQL = "SELECT COUNT(*) FROM test"; var result = entity.Database.SqlQuery<int>(strSQL); // 注意:必須使用迴圈才會真正的去資料庫執行SQL語句,否則不會再資料庫執行SQL語句(EF的延遲載入) foreach(var item in result) { Console.WriteLine("使用者數量:" + item.ToString()); }
執行結果:
在每個資料實體集合DbSet<T>下也有一個SqlQuery(),功能與上面介紹的一樣,只不過DbSet<T>下的SqlQuery()只能返回DbSet<T>中包含的型別,DbSet<T>下的SqlQuery()在返回資料的同時還會讓資料庫上下文(DBContext)跟蹤返回資料的狀態,如果返回的資料發生了修改,就可以使用SaveChanges()將結果直接儲存回資料庫。而Database.SqlQuery()查出的結果則不能跟蹤返回資料的狀態。
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Users.SqlQuery(strSQL).FirstOrDefault(); user.Password = "測試實體下面的SqlQuery方法"; // 呼叫SaveChanges()方法可以更新Password欄位 entity.SaveChanges();
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()查詢出的資料在修改後也能儲存到資料庫,可以使用下面的程式碼:
string strSQL = "SELECT * FROM Users WHERE UserID='002068'"; User user = entity.Database.SqlQuery<User>(strSQL).FirstOrDefault(); user.Password = "測試Database下面的SqlQuery方法"; // 設定這條資料的狀態是:Modified,這樣可以通知資料上下文,這條記錄也被修改了 entity.Entry<User>(user).State = System.Data.Entity.EntityState.Modified; // 呼叫SaveChanges()方法不可以更新Password欄位 entity.SaveChanges();
到此這篇關於Entity Framework中執行sql語句的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45