<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在EF中使用儲存過程和使用檢視是很相似的,一般會使用Database物件上的兩個方法:SqlQuery和ExecuteSqlCommand。為了從儲存過程中讀取很多資料行,我們只需要定義一個類,我們會將檢索到的所有資料行物質化到該類範例的集合中。比如,從下面的儲存過程讀取資料:
CREATE PROCEDURE [dbo].[SelectBooks] @BookTypeName AS NVARCHAR(10) AS BEGIN select B.Name,B.Author,B.PublicationDate,T.BookTypeName from Books as B join BookTypes as T on B.BookTypeId=T.BookTypeId where T.BookTypeName=@BookTypeName END
Book實體類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstProcedureApp.Model { public class Book { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public DateTime PublicationDate { get; set; } public virtual BookType BookType { get; set; } } }
BookType實體類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstProcedureApp.Model { public class BookType { public BookType() { Books = new HashSet<Book>(); } public int BookTypeId { get; set; } public string BookTypeName { get; set; } public virtual ICollection<Book> Books { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstProcedureApp.Model { public class BookFromProcedure { public string Name { get; set; } public string Author { get; set; } public DateTime PublicationDate { get; set; } public string BookTypeName { get; set; } } }
注意:類的屬性名必須和儲存過程中定義的列名一致。
using CodeFirstProcedureApp.Model; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstProcedureApp.EF { public class Initializer : DropCreateDatabaseIfModelChanges<EFDbContext> { protected override void Seed(EFDbContext context) { // 建立初始化資料 BookType bookType = new BookType() { BookTypeName = "文學小說", Books = new List<Book> { new Book(){Name="人間失格",Author="太宰治",PublicationDate=DateTime.Parse("2015-08-01")}, new Book(){Name="解憂雜貨店",Author="東野圭吾",PublicationDate=DateTime.Parse("2014-05-01")}, new Book(){Name="追風箏的人",Author="卡勒德胡賽尼",PublicationDate=DateTime.Parse("2006-08-01")}, new Book(){Name="百年孤獨",Author="加西亞馬爾克斯",PublicationDate=DateTime.Parse("2011-06-01")}, new Book(){Name="霍亂時期的愛情",Author="加西亞馬爾克斯",PublicationDate=DateTime.Parse("2015-06-01")} } }; BookType bookType2 = new BookType() { BookTypeName = "科學", Books = new List<Book> { new Book(){Name="人類簡史",Author="尤瓦爾赫拉利",PublicationDate=DateTime.Parse("2017-01-01")} } }; context.BookTypes.Add(bookType); context.BookTypes.Add(bookType2); base.Seed(context); } } }
using CodeFirstProcedureApp.Model; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstProcedureApp.EF { public class EFDbContext :DbContext { public EFDbContext() : base("name=AppConnection") { Database.SetInitializer(new Initializer()); } // 新增到資料上下文中 public DbSet<Book> Books { get; set; } public DbSet<BookType> BookTypes { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 設定表名和主鍵 modelBuilder.Entity<Book>().ToTable("Books").HasKey(p => p.Id); modelBuilder.Entity<BookType>().ToTable("BookTypes").HasKey(p => p.BookTypeId); // 設定實體關係 // BookType和 Books 一對多關係 外來鍵:BookTypeId modelBuilder.Entity<BookType>().HasMany(p => p.Books).WithRequired(t => t.BookType) .Map(m => { m.MapKey("BookTypeId"); }); base.OnModelCreating(modelBuilder); } } }
使用SQL語句建立儲存過程:
var createSql = @"CREATE PROCEDURE [dbo].[SelectBooks] @BookTypeName AS NVARCHAR(10) AS BEGIN select B.Name,B.Author,B.PublicationDate,T.BookTypeName from Books as B join BookTypes as T on B.BookTypeId=T.BookTypeId where T.BookTypeName=@BookTypeName END"; context.Database.ExecuteSqlCommand(createSql);
檢視資料庫:
呼叫儲存過程查詢資料
注意:在使用儲存過程前,先要在儲存過程中執行該儲存過程或者使用上面的程式生成儲存過程。
var sql = "SelectBooks {0}"; var books = context.Database.SqlQuery<BookFromProcedure>(sql, "文學小說"); books.ToList().ForEach(p => { Console.WriteLine("BookName:" + p.Name + " Author:" + p.Author + " BookTypeName:" + p.BookTypeName + " PublicationDate:" + p.PublicationDate); });
在上面的程式碼中,我們制定了使用哪個類讀取查詢的結果,建立SQL語句時,也為儲存過程的引數提供了一個格式化預留位置,呼叫SqlQuery時為那個引數提供了一個值。假如要提供多個引數的話,多個格式化預留位置必須要用逗號分隔,還要給SqlQuery提供值的陣列。我們也可以使用表值函數代替儲存過程。儲存過程執行結果如下:
另一個用例就是假如儲存過程沒有任何的返回值,只是對資料庫中的一張表或者多張表執行了一條命令的情況。一個儲存過程做了多少事情不重要,重要的是它不返回任何資料。例如:下面的儲存過程只是更新了一些資料:
CREATE PROCEDURE UpdateBooks @name AS NVARCHAR(60), @id as int AS BEGIN UPDATE Books SET Name=@name WHERE Id=@id END
先在資料庫中執行該儲存過程,然後要呼叫該儲存過程,我們使用ExecuteSqlCommand()方法。該方法會返回儲存過程或者其它任何SQL語句受影響的行數。如果對這個返回值不感興趣,可以忽略返回值。
var sql = "UpdateBooks @name,@id"; SqlParameter[] para = new SqlParameter[] { new SqlParameter("@id",1d), new SqlParameter("@name","人間失敗"), }; var book = context.Books.Where(p => p.Id == 1); Console.WriteLine("執行儲存過程前的資料為:"); foreach (var item in book) { Console.WriteLine(item.Name + "t" + item.Author + "t" + item.PublicationDate); } var rowsAffected = context.Database.ExecuteSqlCommand(sql, para); Console.WriteLine("影響的行數為{0}條", rowsAffected); Console.WriteLine("執行儲存過程之後的資料為:"); var books = context.Books.Where(p => p.Id == 1); foreach (var item in books) { Console.WriteLine(item.Name + "t" + item.Author + "t" + item.PublicationDate); }
上面的程式碼中為儲存過程提供了兩個引數:一個是Name,一個是Id。這裡需要注意的是:我們必須嚴格按照它們在儲存過程中定義的順序依次傳入相應的值,它們會以引數陣列傳入ExecuteSqlCommand。執行結果如下:
很大程度上,EF降低了儲存過程的需要。然而,仍舊有很多原因要使用它們。這些原因包括安全標準、遺留資料庫或者效率問題。比如,如果需要在單個操作中更新幾千條資料,然後在通過EF檢索出來;如果每次都更新一行,然後在儲存那些範例,效率是很低的。最後,即使使用了SqlQuery()方法呼叫了儲存過程,也可以更新資料。
注意:開發者可以執行任意的SQL語句,只需要將上面SqlQuery或ExecuteSqlCommand方法中的儲存過程名稱改為要執行的SQL語句就可以了。
範例程式碼下載地址:點此下載
到此這篇關於Entity Framework使用Code First模式管理儲存過程的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援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