Entity Framework使用Code First模式管理視圖
一、什么是視圖
視圖在RDBMS(關(guān)系型數(shù)據(jù)庫管理系統(tǒng))中扮演了一個(gè)重要的角色,它是將多個(gè)表的數(shù)據(jù)聯(lián)結(jié)成一種看起來像是一張表的結(jié)構(gòu),但是沒有提供持久化。因此,可以將視圖看成是一個(gè)原生表數(shù)據(jù)頂層的一個(gè)抽象。例如,我們可以使用視圖提供不同安全的級別,也可以簡化必須編寫的查詢,尤其是我們可以在代碼中的多個(gè)地方頻繁地訪問使用視圖定義的數(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)建視圖的語句中的視圖名一致。
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é)小說",
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="人類簡史",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對象的ExecuteSqlCommand()方法銷毀生成的表,然后又調(diào)用該方法創(chuàng)建我們需要的視圖。該方法在允許開發(fā)者對后端執(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 一對多關(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)行程序,就會看到數(shù)據(jù)庫中已經(jīng)生成了Books和BookTypes兩張表和BookViews視圖,見下圖:

運(yùn)行結(jié)果如下圖:

直接在數(shù)據(jù)庫中查詢視圖:

注意:訪問視圖和任意數(shù)據(jù)表在代碼層面沒有任何區(qū)別,需要注意的地方就是在Seed()方法中定義的視圖名稱要和定義的表名一致,否則就會因?yàn)檎也坏奖韺ο蠖鴪?bào)錯。
示例代碼下載地址:點(diǎn)此下載
到此這篇關(guān)于Entity Framework使用Code First模式管理視圖的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Entity?Framework代碼優(yōu)先(Code?First)模式
- Entity Framework使用Code First模式管理事務(wù)
- Entity Framework使用Code First模式管理存儲過程
- Entity?Framework使用Code?First的實(shí)體繼承模式
- Entity Framework使用Code First模式管理數(shù)據(jù)庫
- EF使用Code First模式生成單數(shù)形式表名
- EF使用Code First模式給實(shí)體類添加復(fù)合主鍵
- 使用EF的Code?First模式操作數(shù)據(jù)庫
- C#筆記之EF Code First 數(shù)據(jù)模型 數(shù)據(jù)遷移
- Entity?Framework代碼優(yōu)先Code?First入門
相關(guān)文章
IE10下Gridview后臺設(shè)置行高不起作用解決方法
GridView1.HeaderStyle.Height=17發(fā)現(xiàn)在IE10 中不起作用,經(jīng)過反復(fù)測試修改為e.Row.Cells[0].Height=17即可解決問題,有類似問題的朋友可以參考下哈2013-04-04
ASP.NET Gridview 中使用checkbox刪除的2種方法實(shí)例分享
ASP.NET Gridview 中使用checkbox刪除的2種方法實(shí)例分享,需要的朋友可以參考一下2013-06-06
asp.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接口來方便調(diào)用。本文就主要介紹了.Net RabbitMQ實(shí)現(xiàn)HTTP API接口調(diào)用,感興趣的可以了解一下2021-06-06
asp.net 用繼承方法實(shí)現(xiàn)頁面判斷session
在做ASP項(xiàng)目的時(shí)候,判斷用戶是否登陸常用的方法是在每個(gè)頁面判斷session是否存在,無奈用java的時(shí)候過濾器就用的不熟。。。還是用繼承吧。汗。。。2009-09-09
.NET下通過HttpListener實(shí)現(xiàn)簡單的Http服務(wù)
這篇文章主要為大家詳細(xì)介紹了.NET下通過HttpListener實(shí)現(xiàn)簡單Http服務(wù)的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-09-09
asp.net頁面master頁面與ascx用戶控件傳值的問題
aspx 頁面,master頁面與ascx用戶控件傳值的問題2010-03-03
asp.net(C#)實(shí)現(xiàn)功能強(qiáng)大的時(shí)間日期處理類完整實(shí)例
這篇文章主要介紹了asp.net(C#)實(shí)現(xiàn)功能強(qiáng)大的時(shí)間日期處理類,封裝了針對日期與時(shí)間的各種常用的判斷與計(jì)算功能,非常方便實(shí)用,需要的朋友可以參考下2016-06-06

