Entity Framework应用:使用Code First模式管理视图
一、什么是视图
视图在RDBMS(关系型数据库管理系统)中扮演了一个重要的角色,它是将多个表的数据联结成一种看起来像是一张表的结构,但是没有提供持久化。因此,可以将视图看成是一个原生表数据顶层的一个抽象。例如,我们可以使用视图提供不同安全的级别,也可以简化必须编写的查询,尤其是我们可以在代码中的多个地方频繁地访问使用视图定义的数据。EF Code First模式现在还不完全支持视图,因此我们必须使用一种变通的方法。这种方法是:将视图真正看成是一张表,让EF定义这张表,然后在删除它,最后再创建一个代替它的视图。
二、使用EF的Code First模式管理视图
以图书和图书类型为例讲解如何使用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 HashSet<Book>();
} public int BookTypeId { get; set; } public string BookTypeName { get; set; } public virtual ICollection<Book> 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
{
/// <summary>
/// 定义配置伙伴类
/// </summary>
public class BookViewMap : EntityTypeConfiguration<BookView>
{
public BookViewMap()
{
// 设置表名
this.ToTable("BookViews");
// 设置主键
HasKey(p => 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 :DropCreateDatabaseAlways<EFDbContext>
{
/// <summary>
/// 重新Seed方法
/// </summary>
/// <param name="context"></param>
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); // 先删除表
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);
}
}
}
上面的代码中,我们先使用Database对象的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 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);
// 设置实体关系
// BookType和 Books 一对多关系 外键: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、运行程序
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 =>
{
Console.WriteLine("Id:" + p.BookId + ",Name:" + p.BookName + ",BookTypeName;" + p.BookTypeName + ",PublicationDate:" + p.PublicationDate);
});
} Console.ReadKey();
}
}
}
运行程序,就会看到数据库中已经生成了Books和BookTypes两张表和BookViews视图,见下图:

运行结果如下图:

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

注意:访问视图和任意数据表在代码层面没有任何区别,需要注意的地方就是在Seed()方法中定义的视图名称要和定义的表名一致,否则就会因为找不到表对象而报错。
示例代码下载地址:https://pan.baidu.com/s/1gf2FzDD
Entity Framework应用:使用Code First模式管理视图的更多相关文章
- Entity Framework应用:Code First模式数据迁移的基本用法
使用Entity Framework的Code First模式在进行数据迁移的时候会遇到一些问题,熟记一些常用的命令很重要,下面整理出了数据迁移时常用的一些命令. 一.模型设计 EF默认使用id字段作 ...
- 学习Entity Framework 中的Code First
这是上周就写好的文章,是在公司浩哥的建议下写的,本来是部门里面分享求创新用的,这里贴出来分享给大家. 最近在对MVC的学习过程中,接触到了Code First这种新的设计模式,感觉很新颖,并且也体验到 ...
- 转载:学习Entity Framework 中的Code First
看完觉得不错,适合作为学习资料,就转载过来了 原文链接:http://www.cnblogs.com/Wayou/archive/2012/09/20/EF_CodeFirst.html 这是上周就写 ...
- Entity Framework 6.x Code Frist For Oracle 实践与注意点
Entity Framework 6.x Code Frist For Oracle 实践与注意点 开发环境 Visual Studio.net 2015/2017 Oracle 11g/12c 数据 ...
- Entity Framework工具POCO Code First Generator的使用
在使用Entity Framework过程中,有时需要借助工具生成Code First的代码,而Entity Framework Reverse POCO Code First Generator是一 ...
- Entity Framework工具POCO Code First Generator的使用(参考链接:https://github.com/sjh37/EntityFramework-Reverse-POCO-Code-First-Generator)
在使用Entity Framework过程中,有时需要借助工具生成Code First的代码,而Entity Framework Reverse POCO Code First Generator是一 ...
- Entity Framework应用:Code First的实体继承模式
Entity Framework的Code First模式有三种实体继承模式 1.Table per Type (TPT)继承 2.Table per Class Hierarchy(TPH)继承 3 ...
- Entity Framework 6.0 Code First(转)
源自:http://www.cnblogs.com/panchunting/tag/Code%20First/ 1 Conventions 2 Custom Conventions 3 Data An ...
- Entity Framework 5.0 Code First全面学习
摘自:http://blog.csdn.net/gentle_wolf/article/details/14004345 不贴图片了,太累. Code First 约定 借助 CodeFirst,可通 ...
随机推荐
- 学会快速装系统 图解硬盘分区软件Norton Ghost使用
http://edu.itbulo.com/200909/126313_5.htm即使你拥有最先进的电脑,采用传统的方法,Windows的安装速度仍然是令人头痛的!有没有什么重装系统的简便方法呢?当然 ...
- 由ConcurrentLinkedQueue扯到线程安全 待整理
前几天项目总是报错,找了下原因. ConcurrentLinkedQueue 本身是一个基于链接节点的无界线程安全队列,你自己调用就不用考虑线程安全了吗? 结论是:原子性操作当然是线程安全的,非原子性 ...
- Android中的Service使用
Service的生命周期 (适用于2.1及以上) 1. 被startService的无论是否有任何活动绑定到该Service,都在后台运行.onCreate(若需要) -> onStart(in ...
- regular expression 练习
练习有一个文件,文件名为output_1981.10.21.txt .下面使用Python: 读取文件名中的日期时间信息,并找出这一天是周几.将文件改名为output_YYYY-MM-DD-W.txt ...
- 修改TreeList单元格格式(实现类似单元格合并效果)
关键点:(1)TreeList中显示的单元格默认不显示上.下.左.右边框,显示的是TreeList自身的行横边框.列纵边框,具体对应TreeList属性中OptionView项下的ShowVertLi ...
- 使用fork并发处理多个client的请求和对等通信p2p
一.在前面讲过的回射客户/服务器程序中,服务器只能处理一个客户端的请求,如何同时服务多个客户端呢?在未讲到select/poll/epoll等高级IO之前,比较老土的办法是使用fork来实现.网络服务 ...
- C#实现相似QQ的隐藏浮动窗口、消息闪动
功能简单介绍 当语音客服系统登录成功进入主界面时,本聊天工具将会自己主动隐藏在左下角位置,当鼠标移动到左下角时,自己主动弹出,当鼠标移开聊天窗口时,自己主动隐藏.假设想让聊天窗口固定在桌面.仅仅要拖动 ...
- STM32 GPIO口模式配置
F103系列 typedef struct { uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. This pa ...
- Hibernate的like用法
直接写String sql = "from ClientInfo as a where a.client_name like '%"+ clientname+"%'&qu ...
- php 解析xml
解析xml,返回一个对象. $obj = simplexml_load_string($XML, 'SimpleXMLElement', LIBXML_NOCDATA); 查看结果var_dump($ ...