EF Core 2.0中如何手动映射数据库的视图为实体
由于Scaffold-DbContext指令目前还不支持自动映射数据库中的视图为实体,所以当我们想使用EF Core来读取数据库视图数据的时候,我们需要手动去做映射,本文介绍如何在EF Core中手动映射数据库的视图为实体。
假设我们在SQL Server中有如下数据库视图[dbo].[V_Person]:
CREATE VIEW [dbo].[V_Person]
AS
SELECT ID, Code, Name, CreateTime, UpdateTime
FROM dbo.Person
GO
其结构如下,共有五列数据:

在EF Core中映射数据库视图有一个硬条件,那就是视图中必须有一列要拥有唯一值,而如果你的视图中没有唯一列请在视图中构造一个唯一列(可以参考这个链接的文章)。这是因为EF Core要求每一个实体要拥有唯一属性(Key),而既然我们要把数据库视图映射为EF Core的实体,那么视图就要求必须有一个唯一列。
本例中数据库视图V_Person的列ID是唯一的。
首先我们定义一个实体类V_Person,用来映射数据库视图V_Person,其属性和数据库视图V_Person的列一一对应:
using System; namespace FFCoreView.Entities
{
/// <summary>
/// 定义实体V_Person,其结构和数据库视图V_Person相同
/// </summary>
public class V_Person
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public DateTime? CreateTime { get; set; }
public DateTime? UpdateTime { get; set; }
}
}
然后我们来构造一个自定义的DbContext类TestDbExContext,其继承于Scaffold-DbContext指令自动生成的DbContext类TestDBContext:
using FFCoreView.Entities;
using Microsoft.EntityFrameworkCore; namespace FFCoreView.Extension
{
/// <summary>
/// TestDbExContext继承TestDBContext,而TestDBContext又继承DbContext
/// </summary>
public class TestDbExContext : TestDBContext
{
/// <summary>
/// 定义一个DbSet<V_Person>的集合属性V_Person,EF Core会自动为其赋值,然后可以利用TestDbExContext.V_Person属性来读取数据库中V_Person视图的数据
/// </summary>
public virtual DbSet<V_Person> V_Person { get; set; } /// <summary>
/// 在重写的OnModelCreating方法中,使用Fluent API来设置实体V_Person和数据库中V_Person视图的关系
/// </summary>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//先调用基类的OnModelCreating方法,设置数据库中其它表和实体的映射关系
base.OnModelCreating(modelBuilder); //接着设置实体V_Person和数据库中V_Person视图的关系
modelBuilder.Entity<V_Person>(entity =>
{
//告诉EF Core实体V_Person对应数据库中的V_Person视图,这里使用entity.ToTable方法后,上面的DbSet<V_Person> V_Person集合属性可以叫任何名字,比如我们可以将其定义为DbSet<V_Person> V_People也可以,如果不使用entity.ToTable方法,那么DbSet<V_Person> V_Person的属性名字必须和数据库视图V_Person的名字相同,否则EF Core会报错
entity.ToTable("V_Person"); //设置实体的唯一属性,因为我们知道数据库中V_Person视图的ID列值是唯一的,所以这里我们设置实体V_Person的Id属性为唯一属性
entity.HasKey(e => e.Id); //利用Fluent API将实体V_Person的每一列映射到数据库视图的每一列
entity.Property(e => e.Id).HasColumnName("ID");
entity.Property(e => e.Code).HasColumnName("Code");
entity.Property(e => e.Name).HasColumnName("Name");
entity.Property(e => e.CreateTime).HasColumnName("CreateTime");
entity.Property(e => e.UpdateTime).HasColumnName("UpdateTime");
});
}
}
}
在我们自定义的TestDbExContext类中,我们定义了个DbSet<V_Person> V_Person集合属性,EF Core会为我们自动为其赋值,我们可以使用这个集合属性来读取数据库视图V_Person的所有数据,然后重写了DbContext的OnModelCreating方法,使用Fluent API来设置了实体V_Person和数据库中V_Person视图的关系。
然后我们在.NET Core控制台项目的Program类Main方法中,来使用自定义的TestDbExContext类读取视图V_Person的数据,注意加上AsNoTracking方法可以提高EF Core读取数据库视图数据的效率, 因为我们不会用实体来更改数据库视图的数据,所以可以用AsNoTracking方法来取消DbContext跟踪实体V_Person:
using FFCoreView.Extension;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq; namespace FFCoreView
{
class Program
{
static void Main(string[] args)
{
using(TestDbExContext dbContext=new TestDbExContext())
{
var vPersons = dbContext.V_Person.AsNoTracking().ToList();//通过TestDbExContext.V_Person属性从数据库中查询视图数据,因为和数据库表不同,我们不会更新数据库视图的数据,所以调用AsNoTracking方法来告诉EF Core不用在DbContext中跟踪返回的V_Person实体,可以提高EF Core的运行效率 Console.WriteLine($"V_Person视图有{vPersons.Count.ToString()}行数据");
} Console.WriteLine("Press any key to quit...");
Console.ReadKey();
}
}
}
运行结果如下,我们成功读出了数据库视图V_Person的三行数据:

注意:
在EF Core 3.0中Scaffold-DbContext指令已经可以自动映射数据库中的视图为实体,所以就不需要采用本文所述的方法了。
EF Core 2.0中如何手动映射数据库的视图为实体的更多相关文章
- EF Core 1.0中使用Include的小技巧
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:由于EF Core暂时不支持Lazy Loading,所以利用Include来加载额外 ...
- MySql 使用 EF Core 2.0 CodeFirst、DbFirst、数据库迁移(Migration)介绍及示例
dotnet core 2.0 发布已经好几天了,期间也把原来 dotnet core 1.1 的 MVC 项目升级到了 2.0,升级过程还是比较顺利的,变动也不是太多.升级的过程中也少不了 Enti ...
- EF Core 2.0中Transaction事务会对DbContext底层创建和关闭数据库连接的行为有所影响
数据库 我们先在SQL Server数据库中建立一个Book表: CREATE TABLE [dbo].[Book]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Cr ...
- EF Core 2.0中怎么用DB First通过数据库来生成实体
要在EF Core使用DB First首先要下载三个Nuget包,在Nuget的Package Manager Console窗口中依次敲入下面三个命令即可: Microsoft.EntityFram ...
- EF Core 2.0 已经支持自动生成父子关系表的实体
现在我们在SQL Server数据库中有Person表如下: CREATE TABLE [dbo].[Person]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Cr ...
- EF Core 2.0 新特性
前言 目前 EF Core 的最新版本为 2.0.0-priview1-final,所以本篇文章主要是针对此版本的一些说明. 注意:如果你要在Visual Studio 中使用 .NET Core 2 ...
- 【译】.NET Core 3.0 中的新变化
.NET Core 3.0 是 .NET Core 平台的下一主要版本.本文回顾了 .Net Core 发展历史,并展示了它是如何从基本支持 Web 和数据工作负载的版本 1,发展成为能够运行 Web ...
- EF Core 2.0 执行原始查询如何防止SQL注入
using (var context = new EFCoreDbContext()) { var searchString = "Jeffcky Wang"; Formattab ...
- [转]【译】.NET Core 3.0 中的新变化
.NET Core 3.0 是 .NET Core 平台的下一主要版本.本文回顾了 .Net Core 发展历史,并展示了它是如何从基本支持 Web 和数据工作负载的版本 1,发展成为能够运行 Web ...
随机推荐
- edge浏览器无法解析<img>的原因
使用<img>标签插入图片,使用谷歌,ie,等浏览器测试,都可以正常显示图片,但是edge浏览器就是实现不了.经过排查测试,不是文件格式的问题,而是路径带有中文.相对路径中虽然不带中文,但 ...
- JAVASE(说出ArrayList,LinkedList的储存性能和特性)
说出ArrayList,和LinkedList的储存性能和特性? 答: ## ArrayList采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,优点是索引读取快,从最后插入和删除元素速 ...
- Windows server 2008 Tips
Tips for remote server in domain. Some Definition user [user] group workgroup domain Local account d ...
- 关于eclipse连接外置android模拟器
1.win+R,输入cmd,打开命令提示符 2.cd D:\Java(安卓应用开发)\adt-bundle-windows-64\sdk\platform-toolsadb connect 127.0 ...
- 把KB转化为KB及以上单位
/** * 把KB转化为KB及以上单位 * @param int $kb * @return string $new_val */ function return_over_kb($kb) { $kb ...
- linux安装redis+RedisDesktopManager
一:redis简介 (REmote DIctionary Server Redis远程字典服务器) 1:Redis是一个开源的使用ANSI C语言编写.完全免费开源的,遵守BSD协议.支持 ...
- javascript使用web proxy来实现ajax cross-domain通信
在现代浏览器中,都强加了对javacript代码的访问限制,比如一个页面的js无法向非同源的url实现ajax请求,获得数据.在这时,是浏览器端会报错: No 'Access-Control-Allo ...
- Azure School 终于上线了,物联网开发课程先走一波~
要说目前最热门的技术是什么,物联网(IoT)肯定荣登榜首!老牌科技企业早已涉足,新晋初创公司层出不穷,就连很多传统企业也开始试水这一领域…… 物联网,说小其实挺小,工业仪表.汽车飞机,甚至家用电器,专 ...
- JpaRepository 查询规范
1.JpaRepository支持接口规范方法名查询.意思是如果在接口中定义的查询方法符合它的命名规则,就可以不用写实现,目前支持的关键字如下. Keyword Sample JPQL snippet ...
- php时间函数大锦集
PHP中的时间函数有这么些:(1)date用法: date(格式,[时间]);如果没有时间参数,则使用当前时间. 格式是一个字符串,其中以下字符有特殊意义:U 替换成从一个起始时间(好象是1970年1 ...