一、什么是视图

视图在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模式管理视图的更多相关文章

  1. Entity Framework应用:Code First模式数据迁移的基本用法

    使用Entity Framework的Code First模式在进行数据迁移的时候会遇到一些问题,熟记一些常用的命令很重要,下面整理出了数据迁移时常用的一些命令. 一.模型设计 EF默认使用id字段作 ...

  2. 学习Entity Framework 中的Code First

    这是上周就写好的文章,是在公司浩哥的建议下写的,本来是部门里面分享求创新用的,这里贴出来分享给大家. 最近在对MVC的学习过程中,接触到了Code First这种新的设计模式,感觉很新颖,并且也体验到 ...

  3. 转载:学习Entity Framework 中的Code First

    看完觉得不错,适合作为学习资料,就转载过来了 原文链接:http://www.cnblogs.com/Wayou/archive/2012/09/20/EF_CodeFirst.html 这是上周就写 ...

  4. Entity Framework 6.x Code Frist For Oracle 实践与注意点

    Entity Framework 6.x Code Frist For Oracle 实践与注意点 开发环境 Visual Studio.net 2015/2017 Oracle 11g/12c 数据 ...

  5. Entity Framework工具POCO Code First Generator的使用

    在使用Entity Framework过程中,有时需要借助工具生成Code First的代码,而Entity Framework Reverse POCO Code First Generator是一 ...

  6. 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是一 ...

  7. Entity Framework应用:Code First的实体继承模式

    Entity Framework的Code First模式有三种实体继承模式 1.Table per Type (TPT)继承 2.Table per Class Hierarchy(TPH)继承 3 ...

  8. Entity Framework 6.0 Code First(转)

    源自:http://www.cnblogs.com/panchunting/tag/Code%20First/ 1 Conventions 2 Custom Conventions 3 Data An ...

  9. Entity Framework 5.0 Code First全面学习

    摘自:http://blog.csdn.net/gentle_wolf/article/details/14004345 不贴图片了,太累. Code First 约定 借助 CodeFirst,可通 ...

随机推荐

  1. checkbox选择框如果被选中value值就可以传过去,没有被选中value就不能穿过去(调试了近一天,坑爹的说)

    因为要适合各种分辨率,所以将原来的单选按钮radio换成单个的checkbox

  2. HDU 2256 Problem of Precision (矩阵乘法)

    Problem of Precision Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  3. 【Linux】文件种类与扩展名

    任何装置在Linux底下都是文件.不仅如此,连数据沟通的接口也有专属的文件在负责-所以,你会了解到,Linux的文件种类真的很多- Linux文件种类 我们在刚刚提到使用『ls -l』观察到第一栏那十 ...

  4. C# 如何调试安装包

    在需要调试的地方插入如下代码即可启动调试:  System.Diagnostics.Debugger.Launch();

  5. python练习笔记——map | sum | pow 的应用

    1 函数简要 map 函数  | sum 函数  |  pow函数  | lambda函数 2 简要计算 2.1 1^2 + 2^2 + 3^2 .....9^2 方法1 print([pow(x,2 ...

  6. 在rhel6上安装Python 2.7和Python 3.3

    安装前,操作系统软件包准备编译python要安装development tools.此外,还要安装一些其他的libs,没有这些libs,python的interpreter可能会无法正常工作 # yu ...

  7. AP_自动付款工作台设定和操作(流程)

    2014-06-04 Created By BaoXinjian

  8. spring 多线程

    http://blog.csdn.net/chszs/article/details/8219189 一.ThreadPoolTaskExecutor ThreadPoolTaskExecutor的配 ...

  9. 基于Vuejs实现 Skeleton Loading 骨架图

    原文地址:https://cloud.tencent.com/developer/article/1006169 https://mp.weixin.qq.com/s/qmyn6mGrO6hRKuvK ...

  10. webservice快速入门-使用wsimport生成ws服务端(二)

    上个例子演示的是在当前项目下发布的Webservice Server,而实际应用中和Client是分离的,本文介绍两种客户端开发方式: 1.导出WebService服务端服务接口到jar包,客户端引入 ...