运维开发网

使用CodeFirst模式管理视图

运维开发网 https://www.qedev.com 2022-08-17 17:08 出处:网络
本文详细讲解了EntityFramework使用CodeFirst模式管理视图的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 一、什么是视图

本文详细讲解了EntityFramework使用CodeFirst模式管理视图的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 一、什么是视图

视图在关系数据库管理系统中起着重要的作用。它将多个表的数据连接成一个看起来像表的结构,但不提供持久性。因此,视图可以被视为本地表数据顶层的抽象。例如,我们可以使用视图来提供不同级别的安全性,还可以简化必须编写的查询。特别是,我们可以在代码的多个地方频繁地访问视图定义的数据。代码优先模式还不完全支持视图,所以我们必须使用一种变通方法。这个方法是:把视图当成一个表,让EF定义这个表,然后删除它,最后创建一个视图替换它。

二、使用EF的Code First模式管理视图

以图书和图书类型为例,讲解如何使用英孚的代码优先模式管理视图。

1、创建实体类

BookType实体类定义如下:

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 HashSetlt;Bookgt;(); } public int BookTypeId { get; set; } public string BookTypeName { get; set; } public Virtual ICollectionlt;Bookgt; Books { get; set; } }}

Book实体类定义如下:

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、创建模拟视图类

从多个实体中取出所需的列,并将它们组合成一个实体。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、为模拟视图类创建配置伙伴类

下面的代码指定了表名和主键。

注意:表名也是视图的名称,这里的表名必须与创建视图的语句中的视图名一致。

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{ /// lt;summarygt; /// 定义配置伙伴类 /// lt;/summarygt; public class BookViewMap : EntityTypeConfigurationlt;BookViewgt; { public BookViewMap() { // 设置表名 this.ToTable("BookViews"); // 设置主键 HasKey(p =gt; p.BookId); } }}4、创建种子数据初始化器类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 :DropCreateDatabaseAlwayslt;EFDbContextgt; { /// lt;summarygt; /// 重新Seed方法 /// lt;/summarygt; /// lt;param name="context"gt;lt;/paramgt; protected override void Seed(EFDbContext context) { // 创建初始化数据 BookType bookType = new BookType() { BookTypeName = "文学小说", Books = new Listlt;Bookgt; { 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 Listlt;Bookgt; { 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); // 创建视图 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); } }}

在上面的代码中,我们首先使用数据库对象的ExecuteSqlCommand()方法销毁生成的表,然后调用这个方法创建我们需要的视图。当允许开发人员在后端执行任意SQL代码时,这种方法非常有用。

5、创建数据上下文类

将实体类添加到数据上下文中,并配置实体之间的关系。

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()); } // 添加到数据上下文中 public DbSetlt;Bookgt; Books { get; set; } public DbSetlt;BookTypegt; BookTypes { get; set; } public DbSetlt;BookViewgt; BookViews { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 配置表名和主键 modelBuilder.Entitylt;Bookgt;().ToTable("Books").HasKey(p =gt; p.Id); modelBuilder.Entitylt;BookTypegt;().ToTable("BookTypes").HasKey(p =gt; p.BookTypeId); // 设置实体关系 // BookType和 Books 一对多关系 外键:BookTypeId modelBuilder.Entitylt;BookTypegt;().HasMany(p =gt; p.Books).WithRequired(t =gt; t.BookType) .Map(m =gt; { m.MapKey("BookTypeId"); }); // 添加配置伙伴类 modelBuilder.Configurations.Add(new BookViewMap()); base.OnModelCreating(modelBuilder); } }}6、运行程序

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()) { // 获取视图的数据 var bookView = context.BookViews; // 循环遍历 bookView.ToList().ForEach(p =gt; { Console.WriteLine("Id:" + p.BookId + ",Name:" + p.BookName + ",BookTypeName;" + p.BookTypeName + ",PublicationDate:" + p.PublicationDate); }); } Console.ReadKey(); } }}

运行该程序,您将看到数据库中已经生成了两个图书和图书类型表以及BookViews视图,如下图所示:


运行结果如下:


直接在数据库中查询视图:


注意:在代码级别访问视图和任何数据表没有区别。需要注意的是,Seed()方法中定义的视图名应该与定义的表名一致,否则会因为找不到表对象而报错。

示例代码下载地址:单击此处下载

关于实体框架使用代码优先模式管理视图的文章到此结束。希望对大家的学习有所帮助

0

精彩评论

暂无评论...
验证码 换一张
取 消