一. 隐藏属性概述

  隐藏属性也叫影子属性,该属性不是在.net实体类中定义的属性,而是在EFCore模型中为该实体类型定义的属性。这些属性的值和状态完全在变更跟踪器中维护。它有二个功能:(1)当数据库中某些字段不想映射到实体类上公开的属性时,隐藏属性非常有用。(2)隐藏属性通常是用于外键属性,其中两个实体之间的关系由数据库中的外键值表示,但是两个实体关系是使用实体类型之间的导航属性进行管理(这个在下面约定中讲到)。

  隐藏属性值可以通过ChangeTracker API获取和更改:

   context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;

  

  下面讲第一个功能:当数据库中某些字段不想映射到实体类上公开的属性时,隐藏属性非常有用

  1.1 配置隐藏属性

    不能通过数据注释来创建隐藏属性,只能通过 Fluent API 来创建, Blog实体中没有映射LastUpdated公开属性,但创建了隐藏属性。

class BloggingContext: DbContext
{
public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().Property<DateTime>("LastUpdated");
}
} public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}

    

  1.2 设置隐藏属性值

    在新增时blog一条数据时,通过ChangeTracker API可以为隐藏属性LastUpdated设置时间值,提交到数据库表中。

          [HttpPost]
public async Task<IActionResult> Create([Bind("Url")] Blog blog)
{
if (ModelState.IsValid)
{
//设置隐藏属性的值
BloggingContext.Entry(blog).Property("LastUpdated").CurrentValue = DateTime.Now;
BloggingContext.Add<Blog>(blog);
await BloggingContext.SaveChangesAsync();
}
return View();
}

      

    

  1.3 读取blog表数据

    可以通过 LINQ 查询中引用隐藏属性EF.Property静态方法,通过隐藏属性LastUpdated排序,读取blog集合数据。

    var blogs = context.Blogs.OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));

二.约定

  下面讲第二个功能,隐藏属性通常用于外键属性。当二个实体存在主从关系,但在依赖实体类中找不到外键属性时,默认是通过"约定"来创建隐藏外键属性的。隐藏外键属性将被命名为<navigation property name><principal key property name>。以下面的示例来说:post依赖实体中包含了隐藏的外键属性 “BlogId ”。

public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; } public List<Post> Posts { get; set; }
} public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; } public Blog Blog { get; set; }
}

  下面简单测试下,通过初例化一个的Post依赖实体,查看该实例中是否包含了BlogId 外键隐藏属性,通过ChangeTracker API来获取,使用断点查看该BlogId 隐藏属性确实存在,只是在Post实体上是非公开的外键属性:

   public void OnGet()
{
object obj = _bloggingContext.Entry(new Post()).Property("BlogId").CurrentValue;
}
_bloggingContext.Entry(new Post()).Property("BlogId")
{Microsoft.EntityFrameworkCore.ChangeTracking.PropertyEntry}
CurrentValue: null
EntityEntry: {Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry}
InternalEntry: {Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry}
IsModified: false
IsTemporary: false
Metadata (Microsoft.EntityFrameworkCore.ChangeTracking.MemberEntry): {Property: Post.BlogId (no field, Nullable<int>) Shadow FK Index }
Metadata: {Property: Post.BlogId (no field, Nullable<int>) Shadow FK Index }
OriginalValue: null

  

参考文献:

    官方文档:EF 隐藏属性

asp.net core系列 25 EF模型配置(隐藏属性)的更多相关文章

  1. asp.net core系列 28 EF模型配置(字段,构造函数,拥有实体类型)

    一. 支持字段 EF允许读取或写入字段而不是一个属性.在使用实体类时,用面向对象的封装来限制或增强应用程序代码对数据访问的语义时,这可能很有用.无法使用数据注释配置.除了约定,还可以使用Fluent ...

  2. asp.net core系列 23 EF模型配置(概述, 类型和属性的包含与排除)

    一.模型配置概述 EF使用一组约定基于实体类的定义来构建模型. 可指定其他配置以补充或替代约定的内容.本系列介绍的配置可应用于面向任何数据存储的模型,以及面向任意关系数据库时可应用的配置. 数据库提供 ...

  3. asp.net core系列 27 EF模型配置(索引,备用键,继承)

    一.索引 索引是许多数据存储中的常见概念.虽然它们在数据存储中的实现可能会有所不同,但它们可用于更有效地基于列(或列集)进行查找.按照约定,用作外键每个属性 (或组的属性) 会自动创建索引.无法使用数 ...

  4. asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)

    一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...

  5. asp.net core系列 24 EF模型配置(主键,生成值,最大长度,并发标记)

    一.主键 键用作每个实体实例的主要唯一标识符. 使用关系数据库时,这会映射到主键的概念. 还可以配置不是主键的唯一标识符.按照约定,名为 Id 或 <type name>Id 的属性会配置 ...

  6. asp.net core系列 26 EF模型配置(实体关系)

    一.概述 EF实体关系定义了两个实体互相关联起来(主体实体和依赖实体的关系,对应数据库中主表和子表关系). 在关系型数据库中,这种表示是通过外键约束来体现.本篇主要讲一对多的关系.先了解下描述关系的术 ...

  7. asp.net core系列 30 EF管理数据库架构--必备知识 迁移

    一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...

  8. asp.net core系列 31 EF管理数据库架构--必备知识 反向工程

    一.   反向工程 反向工程是基于数据库架构,生成的实体类和DbContext类代码的过程,对于Visual Studio开发,建议使用PMC.对于其他开发环境,请选择.NET Core CLI工具( ...

  9. asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)

    一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...

随机推荐

  1. hashMap源码学习记录

    hashMap作为java开发面试最常考的一个题目之一,有必要花时间去阅读源码,了解底层实现原理. 首先,让我们看看hashMap这个类有哪些属性 // hashMap初始数组容量 static fi ...

  2. Python获取当前日期和日期差计算

    在Python中获取日期和时间很简单,主要使用time和datetime包 1.获取当前时间并格式化 from dateutil import rrule from datetime import d ...

  3. vue-nuxtjs

    1.创建项目:npm create-nuxt-app projectName 2.npm i sass-loader node-sass

  4. DHCP工作原理简析

    引言 DHCP是网络体系结构中应用层的一个重要协议,它可以帮助我们对要连接到互联网的计算机进行IP地址等信息的配置.本文从DHCP的原理出发,就DHCP的工作过程 进行详细的探讨. 主要报文 发现报文 ...

  5. 请问浏览器访问www.baidu.com经历了怎样的过程?

    1.查找浏览器缓存 首先会查找浏览器缓存,浏览器会保存一段时间你之前访问过的网址的DNS信息,不同的浏览器保存的时长不等. 2.查找系统缓存 如果上面的步骤没有找到对应的DNS信息,这个时候浏览器会尝 ...

  6. oracle 创建的表为什么在table里没有,但是可以查出来

    有两种的可能: 1这个表在其他用户下创建的,当前用户没有权限访问,此表不在属于当前用户 2查询时写的表名,并不是真正意义的表名,可能指向其他用户,或者就不是这个表

  7. 循环结构for

    教程:高能:语句结构都是由关键字开头,用冒号结束! 一:语句结构 for <variable> in <sequence>:    <statements>else ...

  8. 解决 Visual Studio 点击添加引用无反应的问题

    如遇到vs2010 点击添加引用无反应,主要是因为windows系统推送的更新问题,把windows系统推送的更新都更新一遍就好了. 如果已经安装VS后 Windows系统推荐的更新.360推荐的安全 ...

  9. go 语言的序列化与反序列化

    与c 语言一样, 在网络编程中, go语言同样需要进行序列化与反序列化 在c语言中, 通常需要一块内存缓冲区用来收 发数据.缓冲区一般定义成char *buff类型. 当需要发送 数据时, 直接使用m ...

  10. TCP协议学习总结(上)

    在计算机领域,数据的本质无非0和1,创造0和1的固然伟大,但真正百花齐放的还是基于0和1之上的各种层次之间的组合(数据结构)所带给我们人类各种各样的可能性.例如TCP协议,我们的生活无不无时无刻的站在 ...