“幕后英雄”之Backing Fields【Microsoft Entity Framework Core随笔】
刘德华 有一首歌叫《马桶》,其中有一句歌词是:每一个马桶都是英雄。
EFCore也有一个英雄,在幕后默默地任劳任怨。它就叫 "支持字段" (Backing Fields):
- 中文版:https://docs.microsoft.com/zh-cn/ef/core/modeling/backing-field
支持字段允许 EF 读取和/或写入字段而不是一个属性。 在类中的封装用于限制的使用和/或增强围绕访问数据的语义由应用程序代码,但值应进行读取和/或写入到数据库而无需使用这些限制时这很有用 /增强功能。 - 英文版:https://docs.microsoft.com/en-us/ef/core/modeling/backing-field
Backing fields allow EF to read and/or write to a field rather than a property. This can be useful when encapsulation in the class is being used to restrict the use of and/or enhance the semantics around access to the data by application code, but the value should be read from and/or written to the database without using those restrictions/enhancements. 
它可以用于什么场景呢?简单地说,当我们没有特别地指定类的属性与数据表字段名的话,在装载 数据表的内容 到 类 的时候,EFCore会直接地找到属性名对应的数据表字段名,然后把字段的内容赋值到类属性中(留意,我说的是 类 的 属性 Property,而不是 字段 Field)。但是万一我们不想EFCore这样做呢?例如,以下的俩场景:
- 场景一
我们有一个User类,它有一个叫Password的属性,由于是单向加密,所以希望:每次对它赋值的时候,它都自动做MD5加密;然后对它读取的时候,它都只返回MD5加密后的内容(而不是加密前的内容)
- 场景二
某些金融应用,由于需要支持不同货币品种的小数点后位数精度的要求,金额在数据库储存的时候,或者和内部其他系统做数据交换的时候(通常极有可能是近似于整表导出了),都是整型。然后只有在人机对话的界面,才把进行小数点运算后的结果显示出来。至于货币品种,除了世界各国的货币,还可能会有虚拟货币(你懂得),所以小数点后位数的需求都不一样的啊。
(本篇的例子的程序,可以从 https://github.com/kentliu2007/EFCoreDemo/tree/master/BackingField 下载,建议可以下载后对照着代码来阅读本篇。我用的是 VS2017)
按照上述场景的需求,我们有:
数据表:
- Users



 - Clients, ClientAccountBalance, Currencies
- Clients 的索引


 - ClientAccountBalance 的索引

 - Currencies 的索引


 
 - Clients 的索引
 
- Users
 测试数据:

EF6的实现方式
让我们先来看看如果用EF6怎么做?EF6的话,有设计器啊,轻松容易,毫无压力:- 项目:

 - EF Model Diagram:

 - ClientAccountBalance的设置:

rawAmount的设置,setter和getter都是internal的,因为这个是非 对外(public)属性

 - User的设置:

rawPassword的设置,setter和getter都是internal的,因为这个是非 对外(public)属性

 - 针对场景一的,在Custom目录下,User类的代码:

 - 针对场景二的,在Custom目录下,ClientAccountBalance类的代码:

 
- 项目:
 
大功告成,简单吧?
- EFCore的实现方式
EFCore没有设计器,难道就“臣妾做不到”了吗?其实,借助Backing Fields的话,用EFCore来实现,更简单,更优雅。- Backing Fields两个主要用法:
在 DbContext.OnModelCreating方法里面,- 告诉EFCore,指定 类 的 某个Property,所对照的 类 的 Field 是哪个,且还可以指定它所对照的数据表的字段名:
 
 
 - Backing Fields两个主要用法:
 
modelBuilder.Entity<MyEntity>().Property(b => b.MyProperty).HasField("_myField").HasColumnName("ColumnName");
    - 告诉EFCore,类 的 某个Field ,它所对照的数据表的字段名:
modelBuilder.Entity<MyEntity>().Property("_myField").HasColumnName("ColumnName");
- 项目:

- DbContext的程序(**Backing Fields**出没,请注意):

- 针对场景一的,User的程序:

- 针对场景二的,ClientAccountBalance的程序:

搞定了。单刀直入,简单利索。对吧?
真的就可以吗?好吧,如果不信的话,可以下载代码,跑一下 单元测试 来体验一下嘛 												
“幕后英雄”之Backing Fields【Microsoft Entity Framework Core随笔】的更多相关文章
- Shadow Properties之美(二)【Microsoft Entity Framework Core随笔】
		
接着上一篇Shadow Properties之美(一),我们来继续举一个有点啰嗦的栗子. 先看简单需求:某HR系统,需要记录员工资料.需要记录的资料有: 员工号(规则:分公司所在城市拼音首字母,加上三 ...
 - Shadow Properties之美(一)【Microsoft Entity Framework Core随笔】
		
最近在做公司的项目的时候,开始把部分程序迁移到EF Core,然后有了一些感触,趁着还没忘却,还是先记录下来. EF Core还在成长中,我写这个的时候,版本是2.2.如果对着已有的EF 5/6来说, ...
 - Working with Data » Getting started with ASP.NET Core and Entity Framework Core using Visual Studio » 创建复杂数据模型
		
Creating a complex data model 创建复杂数据模型 8 of 9 people found this helpful The Contoso University sampl ...
 - Entity Framework Core 1.1  升级通告
		
原文地址:https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/ 翻译:杨晓东 ...
 - Entity Framework Core 1.1 Preview 1 简介
		
实体框架核心(EF Core)是Entity Framework的一个轻量级,可扩展和跨平台版本. 10月25日,Entity Framework Core 1.1 Preview 1发布了. 升级到 ...
 - Working with Data »  Getting started with ASP.NET Core and Entity Framework Core using Visual Studio »  排序、筛选、分页以及分组
		
Sorting, filtering, paging, and grouping 7 of 8 people found this helpful By Tom Dykstra The Contoso ...
 - Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制
		
将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...
 - UWP开发之ORM实践:如何使用Entity Framework Core做SQLite数据持久层?
		
选择SQLite的理由 在做UWP开发的时候我们首选的本地数据库一般都是Sqlite,我以前也不知道为啥?后来仔细研究了一下也是有原因的: 1,微软做的UWP应用大部分也是用Sqlite.或者说是微软 ...
 - 全自动迁移数据库的实现 (Fluent NHibernate, Entity Framework Core)
		
在开发涉及到数据库的程序时,常会遇到一开始设计的结构不能满足需求需要再添加新字段或新表的情况,这时就需要进行数据库迁移. 实现数据库迁移有很多种办法,从手动管理各个版本的ddl脚本,到实现自己的mig ...
 
随机推荐
- ES6常用语法(下)
			
Symbol类型 ES5 的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突.如果有一种机 ...
 - Flutter去除右上角Debug标签
			
void main(){ runApp(new MyApp()); } class MyApp extends StatefulWidget { @override _MyAppState creat ...
 - 记python使用grpc
			
using grpc in Python gRPC是基于http/2的RPC框架,使用ProtoBuf作为底层数据序列化.Nginx服务器2018年3月17日引入gRPC支持. gRPC 是用来实现跨 ...
 - VBoxManage
			
虚拟机名称 centos6.9-1 centos6.9-2 centos6.9-3 使用命令开机 虚拟机 VBoxManage startvm 'centos6.9-1' 正常启动 VBoxManag ...
 - CentOS设置服务开机启动的两种方法
			
一.通过服务的方式设置自启动 1. 在/etc/init.d 下建立相关程序的启动脚本 2. chkconfig --add mysqld(添加服务到chkconfig列表中) chkconfig ...
 - Manjaro安装后,应该做的操作,仅作为自己备份使用,如有参考不懂,请留言咨询,或Q609916691
			
家目录下,通用文件夹名称中英文互转: --(1)中文->英文 export LANG=en_US.UTF-8 xdg-user-dirs-update --force --(2)英文->中 ...
 - 【云短信】腾讯&阿里
			
腾讯 : https://github.com/qcloudsms/qcloudsms_csharp 安装nuget包: using qcloudsms_csharp; using System.Co ...
 - kafka consumer 配置详解
			
1.Consumer Group 与 topic 订阅 每个Consumer 进程都会划归到一个逻辑的Consumer Group中,逻辑的订阅者是Consumer Group.所以一条message ...
 - HDU 1041	 Computer Transformation(找规律加大数乘)
			
主要还是找规律,然后大数相乘 #include<stdio.h> #include<string.h> #include<math.h> #include<t ...
 - C#操作PDF文件打印
			
操作PDF文档时,打印是常见的需求之一.针对不同的打印需求,可分多种情况来进行,如设置静默打印.指定打印页码范围和打印纸张大小.双面打印.黑白打印等等.经过测试,下面将对常见的几种PDF打印需求做一些 ...