最近在做公司的项目的时候,开始把部分程序迁移到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随笔】的更多相关文章

  1. Shadow Properties之美(二)【Microsoft Entity Framework Core随笔】

    接着上一篇Shadow Properties之美(一),我们来继续举一个有点啰嗦的栗子. 先看简单需求:某HR系统,需要记录员工资料.需要记录的资料有: 员工号(规则:分公司所在城市拼音首字母,加上三 ...

  2. “幕后英雄”之Backing Fields【Microsoft Entity Framework Core随笔】

    刘德华 有一首歌叫<马桶>,其中有一句歌词是:每一个马桶都是英雄. EFCore也有一个英雄,在幕后默默地任劳任怨.它就叫 "支持字段" (Backing Fields ...

  3. Entity Framework Core 1.1 Preview 1 简介

    实体框架核心(EF Core)是Entity Framework的一个轻量级,可扩展和跨平台版本. 10月25日,Entity Framework Core 1.1 Preview 1发布了. 升级到 ...

  4. 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 ...

  5. 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 ...

  6. 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 ...

  7. Professional C# 6 and .NET Core 1.0 - 38 Entity Framework Core

    本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - 38 Entity Framework ...

  8. Entity Framework Core 生成跟踪列

    本文翻译自<Entity Framework Core: Generate tracking columns>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意:我使用的是 ...

  9. 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 ...

随机推荐

  1. 开发过程中 的一些 补充知识点 + 关于mysql中的日期和时间函数?

    参考: https://www.jb51.net/article/23966.htm https://yq.aliyun.com/articles/260389 mysql中的 日期格式是: HHHH ...

  2. [Redis] - redis实战1

    rememberMe>>>>:null Creating a new SqlSession SqlSession [org.apache.ibatis.session.defa ...

  3. 极其简单的VSCode C++环境配置

    下载我打包的文件VSCode-cpp.7z.001 和 VSCode-cpp.7z.002,解压. 在系统环境变量中添加:你解压的路径\Project\.vscode\MinGW\bin. 打开你解压 ...

  4. error——Fusion log——Debugging Assembly Loading Failures

    原文 So...you're seeing a FileNotFoundException, FileLoadException, BadImageFormatException or you sus ...

  5. zabbix回顾

    1.zabbix能收集哪些信息? 磁盘空间,磁盘IO,cpu负载,内存使用情况,开机时间,网卡的网络流量,进程数等 2.zabbix支持哪些通讯方式? agent:通过专用的代理程序进行监控,是mas ...

  6. JS及相关控件

    1.radio 1)不选中任何值 2)获取选中的值 3)让某个选项选中 4)发生改变时的事件 5)让某个选项不能选 2.CheckBox 1)选中 2)取消 3.select 1)获取下拉框选中项的显 ...

  7. git commit -m 提交的内容换行

    网上说只需要通过单引号来换行,一直没理解,后面终于试出来了.总结一句话就是. . 先输入第一个引号,按Enter即可换行,完成后再补齐后面的引号 // 步骤一: 输入第一行 git commit -m ...

  8. react native 5.54 出ios版本遇到的坑(应该是在xcode10下才会有的吧)记录。。。。。。 据说5.7已经修复了

    1. config.h找不到 rm -r ~/.rncache/cd node_modules/react-native/third-party/glog-0.3.4/./configure --ho ...

  9. Kafka知识总结

    1.kafka是什么 类JMS消息队列,结合JMS中的两种模式,可以有多个消费者主动拉取数据,在JMS中只有点对点模式才有消费者主动拉取数据. kafka是一个生产-消费模型. Producer:生产 ...

  10. git push origin master 上传失败

    http://blog.csdn.net/llf369477769/article/details/51917557 按照网上教程用git把项目上传到github,但是在最后一步git push or ...