Shadow Properties之美(一)【Microsoft Entity Framework Core随笔】
最近在做公司的项目的时候,开始把部分程序迁移到EF Core,然后有了一些感触,趁着还没忘却,还是先记录下来。
EF Core还在成长中,我写这个的时候,版本是2.2。如果对着已有的EF 5/6来说,还有很多功能要迎头赶上的,所以这个也是为什么在.net core 3的标准中,计划要支持EF 6(这个其实是一次性买卖),就是想让大家可以先把.net Core (EF6)用起来,让EF Core先缓口气,等它成长足够了,再迁移到.net Core (EF Core)这样的组合。
即便如此,现在版本的EF Core已经有好多不少的闪亮之处(当然也有一些会因为自己没学好而误会了它的坑)。不论是闪亮点,还是坑,我有时间的话,会缓缓道来。
Shadow Properties这个特性很好,值得先拿出来说一下。但是博客本来就不适宜写得长,不然就不适合碎片阅读。所以我会把它分开来写。而且我还可能会比较啰嗦,有骗字数的嫌疑。
Shadow properties are properties that are not defined in your .NET entity class but are defined for that entity type in the EF Core model. The value and state of these properties is maintained purely in the Change Tracker. (https://docs.microsoft.com/en-us/ef/core/modeling/shadow-properties)
简单地说,隐藏属性 (Shadow Properties),就是那些逻辑设计里面没有的,但是物理设计里面却要有的属性。逻辑设计 vs. 物理设计,是做面向对象编程的攻城狮,都需要面对的问题。例如,那些数据库自增长的ID,审计类字段,还有例如做数据库订阅所需要的时间戳等等。很绕口,让我说人话,就是我们的business class(业务类),是不会包括那些只对照某数据库,或者中间件才冒出来的神马ID之类的属性,而我们却可以在EF Core层面,搞定这些ID的安置方式,而不需要另外再弄一个新的EF class。
有了这个,我们就可以保持逻辑设计的干净,也可以省了再去多弄一个EF Class。或者干脆就着EF Class来细细捣弄(为了继续保持逻辑层的干净)。后述的两种手法,在我们灵活运用EF 5/6的时候,已经屡见不鲜了。
简单举个几个栗子(边幅所限,本篇先来一个个简单的,后面的继续举拖沓的栗子,继续骗字数)。例如,我们会在数据库有一些 LastUpdateBy (记录最后修改者/兼顾新增此记录建立者)、LastUpdateDate(记录最后改动的日期和时间)、CreatedDate(新增此记录的日期和时间)等等,提供简单审计记录功能的字段。但是,我们的Class里面,真心不想要这些属性。这个时候,我们可以继续保持原有business class不变。而在我们的DBContext class的OnModuleCreating方法中,针对某个需要有上述审计字段的Entity,加上这些Shadow Properties。下面的代码片段的例子,只支持UpdateDate和UpdateBy,CreateDate请自行脑补哈(Tips: EntityState.Added 状态下才更新此属性的值)。
public partial class MyDBContext : DbContext
{
…
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
…
modelBuilder.Entity<MyEntity>(entity =>
{
…
addAuditingProperties(entity);
}
}
private void addAuditingProperties(EntityTypeBuilder builder)
{
builder.Property<DateTime?>("LastUpdateDate");
builder.Property<string>("LastUpdateBy");
}
private void setAuditingPropertyValues(EntityEntry entityEntry, string changedBy)
{
//请在调用Context.SaveChanges之前调用一次此方法
…
PropertyEntry propertyEntry;
if (
((propertyEntry = entityEntry.Properties.Where(e => e.Metadata.Name == "LastUpdateDate").FirstOrDefault()) != null) &&
(entityEntry.State == EntityState.Modified)
)
{
propertyEntry.CurrentValue = DateTime.UtcNow;
}
if (
((propertyEntry = entityEntry.Properties.Where(e => e.Metadata.Name == "LastUpdateBy").FirstOrDefault()) != null) &&
((entityEntry.State == EntityState.Modified) || (entityEntry.State == EntityState.Added))
)
{
propertyEntry.CurrentValue = changedBy;
}
...
}
...
}
很简单对吧?只需要偷偷地在自己的DBContext里面捣弄一下,根本不需要让上层建筑知道那么多,我们就支持了仅在数据表里面才有的审计类字段。
接下来,下一篇,会举一个更啰嗦的栗子。解释一下,为什么我们的business class,不应该有那些由于物理设计(落地选型)所带出来的各式各样的神马ID,以及怎么用Shadow Properties来支持。但是因为这个涉及到asp.net core web api的相应改动,所以值得另开一个帖子来骗字数了。
下次见哈。
Shadow Properties之美(一)【Microsoft Entity Framework Core随笔】的更多相关文章
- Shadow Properties之美(二)【Microsoft Entity Framework Core随笔】
接着上一篇Shadow Properties之美(一),我们来继续举一个有点啰嗦的栗子. 先看简单需求:某HR系统,需要记录员工资料.需要记录的资料有: 员工号(规则:分公司所在城市拼音首字母,加上三 ...
- “幕后英雄”之Backing Fields【Microsoft Entity Framework Core随笔】
刘德华 有一首歌叫<马桶>,其中有一句歌词是:每一个马桶都是英雄. EFCore也有一个英雄,在幕后默默地任劳任怨.它就叫 "支持字段" (Backing Fields ...
- 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 » 创建复杂数据模型
Creating a complex data model 创建复杂数据模型 8 of 9 people found this helpful The Contoso University sampl ...
- 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 ...
- Working with Data » 使用Visual Studio开发ASP.NET Core MVC and Entity Framework Core初学者教程
原文地址:https://docs.asp.net/en/latest/data/ef-mvc/intro.html The Contoso University sample web applica ...
- Professional C# 6 and .NET Core 1.0 - 38 Entity Framework Core
本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - 38 Entity Framework ...
- Entity Framework Core 生成跟踪列
本文翻译自<Entity Framework Core: Generate tracking columns>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意:我使用的是 ...
- Professional C# 6 and .NET Core 1.0 - Chapter 38 Entity Framework Core
本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - Chapter 38 Entity F ...
随机推荐
- Synchronized使用方法
Synchronized是我们常用来维持线程安全时使用的一个关键字,内部通过monitor(监视器锁,由C++实现)来实现.而monitor本质又是依赖底层操作系统的mutex lock来实现.而操作 ...
- iOS SDWebImage知识点
1.clear 和 clean clear 先把之前的缓存文件夹删除掉,然后新建一个文件夹 clean 先删除过期的文件,然后计算剩余缓存文件的大小 currentSize > maxSize, ...
- Python游戏编程入门4
Math和Graphics:Analog Clock示例程序本章介绍Python的math模块,该模块可以执行计算,如常见的三角正弦函数.余弦函数.正切函数等. 使用正弦和余弦函数绘制圆创建Anlog ...
- Ubuntu 远程 Jupyter 配置
Ubuntu 远程 Jupyter 配置 每次上课都要重新部署环境,最近看到阿里云的大学生优惠活动,就着手了一台云服务器,于是就把环境部署在上面了. 环境:阿里云 Ubuntu 16.04 64位 新 ...
- Office DCOM 组件交互权限设置
这里以 WORD 为例: 运行 mmc -32 打开控制台. 点击 文件 -> 添加/删除管理单元 ,在 可用的管理单元 中选择 组件服务 ,然后点击 添加 , 确定 . 展开 组件服务节 点直 ...
- MySQL及navicat for mysql中文乱码
转载自:https://www.cnblogs.com/mufire/p/6697994.html 修改完之后记着重启mysql服务,在服务里边重启,即可生效! 全部使用utf8编码 MySQL中文乱 ...
- JQuery Checkbox 获取多选值 Checkbox选中个数
1.获取checkbox选中个数 $("input[name='ckb-jobid']:checked").length $("input[type='checkbox' ...
- laravel 框架的 csrf
由于 laravel 框架自带 csrf 防护, 也就是通过中间件验证请求的 token, 所以 form 表单必须如下设置才可以正常提交, 否则会 419: <form method=&quo ...
- grep 从文件内容中查找
grep -rin [查找目标] [查找范围] 例子:在当前目录下的文件内查找test字符串 grep -rin test ./
- Axure下拉列表的交互事件 + 自定义元件库
下拉列表的交互事件: 场景:当点击第一个下拉列表框的江苏时,第二个列表框会显示江苏省的城市:当点击第一个下拉列表框的北京时,第二个列表框会显示北京市的区 操作:把第二个列表框设置为动态面板,设置为两种 ...