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 ...
随机推荐
- js for循环中点击事件中无法获取每一个i值的问题
好像是第二次遇到这个问题,必须要总结一下!! <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...
- 20个实用便捷的CSS3工具、库及实例
编者按:坊间传闻,有本CSS的高手炼成秘籍在江湖失传已久,书中所载,多为最新的惊人技术与实例示范,是为集大成者,一旦学成,代码效率猛增,功力提升数倍,今日偶获,不敢怠慢,赶紧发到优设,望人人受益.说人 ...
- drupal 开发笔记
“以前我在开发Java项目的时候,都需要自己设计数据库表结构,数据库表结构的设计关系到一个人开发技能的高低,而在Drupal里面,我们通常是不需要设计数据库表结构,我们要做的是创建新的内容类型,然后为 ...
- Reporting Service 2005 迁移 到 2008
1. 备份ReportServer 和ReportServerTempDB 的数据库. 2. 在Reporting Services Configuration Manager 中备份Encrypti ...
- LeetCode赛题391----Perfect Rectangle
#391. Perfect Rectangle Given N axis-aligned rectangles where N > 0, determine if they all togeth ...
- 解决servlet在web.xml中的路径跳转问题
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" ...
- Android 解决NestedScrollView 嵌套 RecyclerView出现的卡顿,上拉刷新无效
解决卡顿的方法最简单的就是设置RecyclerView的android:nestedScrollingEnabled="false",放弃自己的滑动,交给外部的NestedScro ...
- 使用 js 实现文本过多时隐藏部分文本
使用 js 实现文本过多时隐藏部分文本 情景描述: 有时候我们需要显示部分文字,就像 QQ 空间这样,先显示部分文字,加一个[查看全文],让用户选择是否查看全部 解决方法: 第一步:在一个 id 为 ...
- 数值的整数次方(C++ 和 Python 实现)
(说明:本博客中的题目.题目详细说明及参考代码均摘自 “何海涛<剑指Offer:名企面试官精讲典型编程题>2012年”) 题目 实现函数 double Power(double base, ...
- FTP作业
实现一个FTP网盘的功能 pa's's