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的三行数据:

原文地址:https://www.cnblogs.com/OpenCoder/p/9807129.html

时间: 2024-08-28 13:10:54

EF Core 2.0中如何手动映射数据库的视图为实体的相关文章

【译】.NET Core 3.0 中的新变化

.NET Core 3.0 是 .NET Core 平台的下一主要版本.本文回顾了 .Net Core 发展历史,并展示了它是如何从基本支持 Web 和数据工作负载的版本 1,发展成为能够运行 Web.桌面.机器学习.容器.IoT 等的版本 3.0. .NET Core 1 .NET Core 的历史可追溯到几年前,版本 1 是在 2016 年推出,旨在生成第一版开放源代码和跨平台(Windows.macOS 和 Linux)的 .NET.灵感来源于只能使用开放源代码框架的客户,以及需要在 Li

EF Core 2.1 中的新增功能(2)

安装 EF Core 将 EF Core 添加到不同平台和常用 IDE 中的应用程序的所需步骤汇总. 分步入门教程 无需具备 Entity Framework Core 或任何特定 IDE 的原有知识,即可学习这些入门教程. 这些教程将逐步介绍如何创建用于查询和保存数据库中数据的简单应用程序. 我们已提供许多教程,指导你开始使用各种操作系统和应用程序类型. Entity Framework Core 可基于现有数据库创建模型,也可基于模型创建数据库. 提供的教程演示了这两种方法. .NET Fr

EF Core 2.0使用MsSql/Mysql实现DB First和Code First

参考地址 Entity Framework官网 ASP.NET Core MVC 和 EF Core - 教程系列 环境 Visual Studio 2017 最新版本的.NET Core 2.0 SDK 最新版本的 Windows PowerShell 开始搭建 1.在 Visual Studio 2017 中创建新项目 "文件">"新建">"项目" 从左侧菜单中选择"已安装">"模板"

在ASP.NET Core 2.0中使用CookieAuthentication

在ASP.NET Core中关于Security有两个容易混淆的概念一个是Authentication(认证),一个是Authorization(授权).而前者是确定用户是谁的过程,后者是围绕着他们允许做什么,今天的主题就是关于在ASP.NET Core 2.0中如何使用CookieAuthentication认证. 在ASP.NET Core 2.0中使用CookieAuthentication跟在1.0中有些不同,需要在ConfigureServices和Configure中分别设置,前者我

说说ASP.Net Core 2.0中的Razor Page

随着.net core2.0的发布,我们可以创建2.0的web应用了.2.0中新东西的出现,会让我们忘记老的东西,他就是Razor Page.下面的这篇博客将会介绍ASP.Net Core 2.0中的Razor Page. 在ASP.Net Core 2.0新特点之一就是支持Razor Page.今天的Razor Page是ASP.Net Core MVC中的一个子集.ASP.Net Core MVC 支持Razor Page意味着Razor Page应用从技术上来说就是MVC应用,同时Razo

用ASP.NET Core 1.0中实现邮件发送功能

准备将一些项目迁移到 asp.net core 先从封装类库入手,在遇到邮件发送类时发现在 asp.net core 1.0中并示提供SMTP相关类库,于是网上一搜发现了MailKit 好东西一定要试一下,何况是开源,下面是代码可实现SMTP邮件发送: using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; using System.Threading.Tasks; namespace ConsoleApp1 { public

ASP.NET Core 1.0 中使用 Swagger 生成文档

github:https://github.com/domaindrivendev/Ahoy 之前文章有介绍在ASP.NET WebAPI 中使用Swagger生成文档,ASP.NET Core 1.0中同样也支持. 依赖包 "dependencies": { "Swashbuckle.SwaggerGen": "6.0.0-rc1-final", "Swashbuckle.SwaggerUi": "6.0.0-rc

.NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介

.NET Core 1.0.ASP.NET Core 1.0和EF Core 1.0简介 英文原文:Reintroducing .NET Core 1.0, ASP.NET Core 1.0, and EF Core 1.0 新版本的 ASP.NET 和 Entity Framework 有一个严重的问题,就是它们同以前的版本不兼容.这不只是行为或 API 稍有差异的事,而基本上是进行了完全的重写,去掉了大量的功能. 因此,目前人们认为,将这些框架称为 ASP.NET 5.0 和 Entity

正在开发的一个以最简化的操作在 .NET Core 1.0 中处理微信请求的SDK

现有的微信SDK库在 .NET Core 1.0 中表示很有压力,比如 Deepleo.Weixin.SDK 和 Senparc.Weixin(即使现有一个转移到.NET Core 1.0的初始项目,但是暂时还不能用) .前者轻量后者全而轻便,但是按照我的个人观点看来,前者太轻便了,对于不记参数的我来说点不出来就等于白搭,后者需要自定义一个处理方法来执行相关任务,但是相关的类型对于我这个就爱点出来能解决的事绝不干多余的是的我来说,还是不大乐意去用.因此就结合两者自行开发一个适合自己使用的SDK库