Entity Framework使用Code First模式管理視圖
一、什么是視圖
視圖在RDBMS(關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng))中扮演了一個(gè)重要的角色,它是將多個(gè)表的數(shù)據(jù)聯(lián)結(jié)成一種看起來(lái)像是一張表的結(jié)構(gòu),但是沒有提供持久化。因此,可以將視圖看成是一個(gè)原生表數(shù)據(jù)頂層的一個(gè)抽象。例如,我們可以使用視圖提供不同安全的級(jí)別,也可以簡(jiǎn)化必須編寫的查詢,尤其是我們可以在代碼中的多個(gè)地方頻繁地訪問(wèn)使用視圖定義的數(shù)據(jù)。EF Code First模式現(xiàn)在還不完全支持視圖,因此我們必須使用一種變通的方法。這種方法是:將視圖真正看成是一張表,讓EF定義這張表,然后在刪除它,最后再創(chuàng)建一個(gè)代替它的視圖。
二、使用EF的Code First模式管理視圖
以圖書和圖書類型為例講解如何使用EF的Code First模式管理視圖。
1、創(chuàng)建實(shí)體類
BookType實(shí)體類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstViewApp.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; } } }
Book實(shí)體類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstViewApp.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; } } }
2、創(chuàng)建模擬視圖類
從多個(gè)實(shí)體中取出想要的列組合成一個(gè)實(shí)體,BookView模擬視圖類定義如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstViewApp.Model { public class BookView { public int BookId { get; set; } public string BookName { get; set; } public string Author { get; set; } public DateTime PublicationDate { get; set; } public string BookTypeName { get; set; } } }
3、為模擬視圖類創(chuàng)建配置伙伴類
下面的代碼指定了表名和主鍵。
注意:表名也是視圖的名字,這里的表名一定要和創(chuàng)建視圖的語(yǔ)句中的視圖名一致。
using CodeFirstViewApp.Model; using System; using System.Collections.Generic; using System.Data.Entity.ModelConfiguration; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstViewApp.Map { /// <summary> /// 定義配置伙伴類 /// </summary> public class BookViewMap : EntityTypeConfiguration<BookView> { public BookViewMap() { // 設(shè)置表名 this.ToTable("BookViews"); // 設(shè)置主鍵 HasKey(p => p.BookId); } } }
4、創(chuàng)建種子數(shù)據(jù)初始化器類
using CodeFirstViewApp.Model; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstViewApp.EF { public class Initializer :DropCreateDatabaseAlways<EFDbContext> { /// <summary> /// 重新Seed方法 /// </summary> /// <param name="context"></param> protected override void Seed(EFDbContext context) { // 創(chuàng)建初始化數(shù)據(jù) BookType bookType = new BookType() { BookTypeName = "文學(xué)小說(shuō)", 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="追風(fēng)箏的人",Author="卡勒德胡賽尼",PublicationDate=DateTime.Parse("2006-08-01")}, new Book(){Name="百年孤獨(dú)",Author="加西亞馬爾克斯",PublicationDate=DateTime.Parse("2011-06-01")}, new Book(){Name="霍亂時(shí)期的愛情",Author="加西亞馬爾克斯",PublicationDate=DateTime.Parse("2015-06-01")} } }; BookType bookType2 = new BookType() { BookTypeName = "科學(xué)", Books = new List<Book> { new Book(){Name="人類簡(jiǎn)史",Author="尤瓦爾赫拉利",PublicationDate=DateTime.Parse("2017-01-01")} } }; context.BookTypes.Add(bookType); context.BookTypes.Add(bookType2); // 先刪除表 var drop = "Drop Table BookViews"; context.Database.ExecuteSqlCommand(drop); // 創(chuàng)建視圖 var createView = @"CREATE VIEW [dbo].[BookViews] AS SELECT dbo.Books.Id AS BookId, dbo.Books.Name AS BookName, dbo.Books.Author AS Author, dbo.Books.PublicationDate AS PublicationDate, dbo.BookTypes.BookTypeName AS BookTypeName FROM dbo.Books INNER JOIN dbo.BookTypes ON dbo.BookTypes.BookTypeId=dbo.Books.BookTypeId"; context.Database.ExecuteSqlCommand(createView); base.Seed(context); } } }
上面的代碼中,我們先使用Database對(duì)象的ExecuteSqlCommand()方法銷毀生成的表,然后又調(diào)用該方法創(chuàng)建我們需要的視圖。該方法在允許開發(fā)者對(duì)后端執(zhí)行任意的SQL代碼時(shí)很有用。
5、創(chuàng)建數(shù)據(jù)上下文類
把實(shí)體類添加到數(shù)據(jù)上下文中,并配置實(shí)體之間的關(guān)系
using CodeFirstViewApp.Map; using CodeFirstViewApp.Model; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstViewApp.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; } public DbSet<BookView> BookViews { 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); // 設(shè)置實(shí)體關(guān)系 // BookType和 Books 一對(duì)多關(guān)系 外鍵:BookTypeId modelBuilder.Entity<BookType>().HasMany(p => p.Books).WithRequired(t => t.BookType) .Map(m => { m.MapKey("BookTypeId"); }); // 添加配置伙伴類 modelBuilder.Configurations.Add(new BookViewMap()); base.OnModelCreating(modelBuilder); } } }
6、運(yùn)行程序
Main()方法定義如下:
using CodeFirstViewApp.EF; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeFirstViewApp { class Program { static void Main(string[] args) { using (var context = new EFDbContext()) { // 獲取視圖的數(shù)據(jù) var bookView = context.BookViews; // 循環(huán)遍歷 bookView.ToList().ForEach(p => { Console.WriteLine("Id:" + p.BookId + ",Name:" + p.BookName + ",BookTypeName;" + p.BookTypeName + ",PublicationDate:" + p.PublicationDate); }); } Console.ReadKey(); } } }
運(yùn)行程序,就會(huì)看到數(shù)據(jù)庫(kù)中已經(jīng)生成了Books和BookTypes兩張表和BookViews視圖,見下圖:
運(yùn)行結(jié)果如下圖:
直接在數(shù)據(jù)庫(kù)中查詢視圖:
注意:訪問(wèn)視圖和任意數(shù)據(jù)表在代碼層面沒有任何區(qū)別,需要注意的地方就是在Seed()方法中定義的視圖名稱要和定義的表名一致,否則就會(huì)因?yàn)檎也坏奖韺?duì)象而報(bào)錯(cuò)。
示例代碼下載地址:點(diǎn)此下載
到此這篇關(guān)于Entity Framework使用Code First模式管理視圖的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Entity?Framework代碼優(yōu)先(Code?First)模式
- Entity Framework使用Code First模式管理事務(wù)
- Entity Framework使用Code First模式管理存儲(chǔ)過(guò)程
- Entity?Framework使用Code?First的實(shí)體繼承模式
- Entity Framework使用Code First模式管理數(shù)據(jù)庫(kù)
- EF使用Code First模式生成單數(shù)形式表名
- EF使用Code First模式給實(shí)體類添加復(fù)合主鍵
- 使用EF的Code?First模式操作數(shù)據(jù)庫(kù)
- C#筆記之EF Code First 數(shù)據(jù)模型 數(shù)據(jù)遷移
- Entity?Framework代碼優(yōu)先Code?First入門
相關(guān)文章
IE10下Gridview后臺(tái)設(shè)置行高不起作用解決方法
GridView1.HeaderStyle.Height=17發(fā)現(xiàn)在IE10 中不起作用,經(jīng)過(guò)反復(fù)測(cè)試修改為e.Row.Cells[0].Height=17即可解決問(wèn)題,有類似問(wèn)題的朋友可以參考下哈2013-04-04ASP.NET Gridview 中使用checkbox刪除的2種方法實(shí)例分享
ASP.NET Gridview 中使用checkbox刪除的2種方法實(shí)例分享,需要的朋友可以參考一下2013-06-06asp.net 1.1/ 2.0 中快速實(shí)現(xiàn)單點(diǎn)登陸
asp.net 1.1/ 2.0 中快速實(shí)現(xiàn)單點(diǎn)登陸...2007-04-04.Net RabbitMQ實(shí)現(xiàn)HTTP API接口調(diào)用
RabbitMQ Management插件還提供了基于RESTful風(fēng)格的HTTP API接口來(lái)方便調(diào)用。本文就主要介紹了.Net RabbitMQ實(shí)現(xiàn)HTTP API接口調(diào)用,感興趣的可以了解一下2021-06-06asp.net 用繼承方法實(shí)現(xiàn)頁(yè)面判斷session
在做ASP項(xiàng)目的時(shí)候,判斷用戶是否登陸常用的方法是在每個(gè)頁(yè)面判斷session是否存在,無(wú)奈用java的時(shí)候過(guò)濾器就用的不熟。。。還是用繼承吧。汗。。。2009-09-09.NET下通過(guò)HttpListener實(shí)現(xiàn)簡(jiǎn)單的Http服務(wù)
這篇文章主要為大家詳細(xì)介紹了.NET下通過(guò)HttpListener實(shí)現(xiàn)簡(jiǎn)單Http服務(wù)的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-09-09asp.net頁(yè)面master頁(yè)面與ascx用戶控件傳值的問(wèn)題
aspx 頁(yè)面,master頁(yè)面與ascx用戶控件傳值的問(wèn)題2010-03-03asp.net(C#)實(shí)現(xiàn)功能強(qiáng)大的時(shí)間日期處理類完整實(shí)例
這篇文章主要介紹了asp.net(C#)實(shí)現(xiàn)功能強(qiáng)大的時(shí)間日期處理類,封裝了針對(duì)日期與時(shí)間的各種常用的判斷與計(jì)算功能,非常方便實(shí)用,需要的朋友可以參考下2016-06-06