Entity Framework使用Code First模式管理存儲過程
在EF中使用存儲過程和使用視圖是很相似的,一般會使用Database對象上的兩個方法:SqlQuery和ExecuteSqlCommand。為了從存儲過程中讀取很多數(shù)據(jù)行,我們只需要定義一個類,我們會將檢索到的所有數(shù)據(jù)行物質化到該類實例的集合中。比如,從下面的存儲過程讀取數(shù)據(jù):
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
1、定義實體類
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; } } }
2、定義與存儲過程結果匹配的實體類
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; } } }
注意:類的屬性名必須和存儲過程中定義的列名一致。
3、創(chuàng)建種子初始化器類
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) { // 創(chuàng)建初始化數(shù)據(jù) 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); } } }
4、定義數(shù)據(jù)上下文類
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()); } // 添加到數(shù)據(jù)上下文中 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); } } }
5、運行程序
使用SQL語句創(chuàng)建存儲過程:
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);
查看數(shù)據(jù)庫:
調用存儲過程查詢數(shù)據(jù)
注意:在使用存儲過程前,先要在存儲過程中執(zhí)行該存儲過程或者使用上面的程序生成存儲過程。
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); });
在上面的代碼中,我們制定了使用哪個類讀取查詢的結果,創(chuàng)建SQL語句時,也為存儲過程的參數(shù)提供了一個格式化占位符,調用SqlQuery時為那個參數(shù)提供了一個值。假如要提供多個參數(shù)的話,多個格式化占位符必須要用逗號分隔,還要給SqlQuery提供值的數(shù)組。我們也可以使用表值函數(shù)代替存儲過程。存儲過程執(zhí)行結果如下:
6、執(zhí)行無返回值的存儲過程
另一個用例就是假如存儲過程沒有任何的返回值,只是對數(shù)據(jù)庫中的一張表或者多張表執(zhí)行了一條命令的情況。一個存儲過程做了多少事情不重要,重要的是它不返回任何數(shù)據(jù)。例如:下面的存儲過程只是更新了一些數(shù)據(jù):
CREATE PROCEDURE UpdateBooks @name AS NVARCHAR(60), @id as int AS BEGIN UPDATE Books SET Name=@name WHERE Id=@id END
先在數(shù)據(jù)庫中執(zhí)行該存儲過程,然后要調用該存儲過程,我們使用ExecuteSqlCommand()方法。該方法會返回存儲過程或者其它任何SQL語句受影響的行數(shù)。如果對這個返回值不感興趣,可以忽略返回值。
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("執(zhí)行存儲過程前的數(shù)據(jù)為:"); foreach (var item in book) { Console.WriteLine(item.Name + "\t" + item.Author + "\t" + item.PublicationDate); } var rowsAffected = context.Database.ExecuteSqlCommand(sql, para); Console.WriteLine("影響的行數(shù)為{0}條", rowsAffected); Console.WriteLine("執(zhí)行存儲過程之后的數(shù)據(jù)為:"); var books = context.Books.Where(p => p.Id == 1); foreach (var item in books) { Console.WriteLine(item.Name + "\t" + item.Author + "\t" + item.PublicationDate); }
上面的代碼中為存儲過程提供了兩個參數(shù):一個是Name,一個是Id。這里需要注意的是:我們必須嚴格按照它們在存儲過程中定義的順序依次傳入相應的值,它們會以參數(shù)數(shù)組傳入ExecuteSqlCommand。執(zhí)行結果如下:
很大程度上,EF降低了存儲過程的需要。然而,仍舊有很多原因要使用它們。這些原因包括安全標準、遺留數(shù)據(jù)庫或者效率問題。比如,如果需要在單個操作中更新幾千條數(shù)據(jù),然后在通過EF檢索出來;如果每次都更新一行,然后在保存那些實例,效率是很低的。最后,即使使用了SqlQuery()方法調用了存儲過程,也可以更新數(shù)據(jù)。
注意:開發(fā)者可以執(zhí)行任意的SQL語句,只需要將上面SqlQuery或ExecuteSqlCommand方法中的存儲過程名稱改為要執(zhí)行的SQL語句就可以了。
示例代碼下載地址:點此下載
到此這篇關于Entity Framework使用Code First模式管理存儲過程的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Entity?Framework代碼優(yōu)先(Code?First)模式
- Entity Framework使用Code First模式管理事務
- Entity Framework使用Code First模式管理視圖
- Entity?Framework使用Code?First的實體繼承模式
- Entity Framework使用Code First模式管理數(shù)據(jù)庫
- EF使用Code First模式生成單數(shù)形式表名
- EF使用Code First模式給實體類添加復合主鍵
- 使用EF的Code?First模式操作數(shù)據(jù)庫
- C#筆記之EF Code First 數(shù)據(jù)模型 數(shù)據(jù)遷移
- Entity?Framework代碼優(yōu)先Code?First入門
相關文章
ASP.NET2.0:頁面中鏈入的CSS、js文件帶中文時需注意
ASP.NET2.0:頁面中鏈入的CSS、js文件帶中文時需注意...2006-09-09SQL Server 2008 R2:error 26 開啟遠程連接詳解
本篇文章小編為大家介紹,SQL Server 2008 R2:error 26 開啟遠程連接詳解。需要的朋友參考下2013-04-04ASP.NET MVC Webuploader實現(xiàn)上傳功能
這篇文章主要為大家詳細介紹了ASP.NET MVC Webuploader實現(xiàn)上傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09Asp.net Core 3.1基于AspectCore實現(xiàn)AOP實現(xiàn)事務、緩存攔截器功能
這篇文章主要介紹了Asp.net Core 3.1基于AspectCore實現(xiàn)AOP實現(xiàn)事務、緩存攔截器功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12