DDD Code First 迁移数据实现EF CORE的软删除,值对象迁移配置
感谢Jeffcky大佬的博客:
EntityFramework Core 2.0全局过滤 (HasQueryFilter) https://www.cnblogs.com/CreateMyself/p/8491058.html
什么是值对象
没有唯一的标识,固定不变的,表示一个具体的概念,用来描述一个东西的特征,代表是什么,使用时直接添加或替换,值对象在迁移时,会以字段的形式迁移到数据库中
软删除
定义删除的接口
public interface ISoftDelete
{
bool IsDeleted { get; set; }
}
创建模型实现ISoftDelete接口
public class UserInfo : IAggregationRoot, ISoftDelete
{
public Guid Id { get; set; }
public string UserName { get; private set; }
public string UserPassword { get; private set; }
public string UserPhone { get; private set; }
public Address Address { get; private set; }
public bool IsDeleted { get; set; }
}
[Owned]
public class Address:IValueObject
{
public string Province { get;private set; }
public string City { get; private set; }
public string County { get; private set; }
public string AddressDetails { get; private set; }
}
Lamda的扩展以及Code First 迁移配置
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//设置软删除
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var parameter = Expression.Parameter(entityType.ClrType);
//查询类上面是否有Owned(值对象)的特性
var ownedModelType = parameter.Type;
var ownedAttribute = Attribute.GetCustomAttribute(ownedModelType, typeof(OwnedAttribute));
if (ownedAttribute == null)
{
var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool));
var isDeletedProperty =
Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted"));
BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty,
Expression.Constant(false));
var lambda = Expression.Lambda(compareExpression, parameter);
modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambda);
}
}
}
在这里需要过滤掉值对象的类,在值对象的类上面声明一个特性,通过该特性过滤掉该值对象, 如果该类是值对象就直接跳过,不过滤值对象EF CORE会给值对象附加一个IsDeleted的字段,EF CORE执行中会报错,提示找不到该字段
Owned是EF CORE 配置值对象的特性,可以去自定义特性,在每一个值对象上面声明,在OnModelCreating 过滤掉包含这个特性的类
最终实现的代码:
public async Task>> GetUserList(SearchUserDto input)
{
Expression> where = e => e.IsDisable == false;
if (!string.IsNullOrEmpty(input.SearchName))
{
where = where.And(e => e.UserName.Contains(input.SearchName));
}
if (!string.IsNullOrEmpty(input.SearchPwd))
{
where = where.And(e => e.UserPhone.Contains(input.SearchPwd));
}
var userList = await _userRepository.LoadEntityListAsync(where, e => e.UserName, "asc", input.PageIndex, input.Pagesize);
var total = await _userRepository.GetEntitiesCountAsync(where);
var userDtoList = userList.MapToList<UserInfo, UserDto>();
HeaderResult<List<UserDto>> result = new HeaderResult<List<UserDto>>
{
IsSucceed = true,
Result = userDtoList,
Total = total
};
return result;
}
</pre>
DDD Code First 迁移数据实现EF CORE的软删除,值对象迁移配置的更多相关文章
- ef core实现软删除
很多web程序一般的偶不会设计真的物理删除了. 基本上都是在在数据库加一个标记,就得当作已经删除了.同时在查询的时候,过滤已经标记删除的数据 ef core实现软删除是非常简单的,直接在OnModel ...
- ASP.NET Core Identity 迁移数据 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Identity 迁移数据 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 迁移数据 上一章节中我们配置了 ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- DDD 领域驱动设计-三个问题思考实体和值对象(续)
上一篇:DDD 领域驱动设计-三个问题思考实体和值对象 说实话,整理现在这一篇博文的想法,在上一篇发布出来的时候就有了,但到现在才动起笔来,而且写之前又反复读了上一篇博文的内容及评论,然后去收集资料, ...
- DDD 领域驱动设计-三个问题思考实体和值对象
消息场景:用户 A 发送一个消息给用户 B,用户 B 回复一个消息给用户 A... 现有设计:消息设计为实体并为聚合根,发件人.收件人设计为值对象. 三个问题: 实体最重要的特性是什么? Messag ...
- EF Core的级联删除
级联删除由DeleteBehavior的枚举值来设置: 行为名称 对内存中的依赖项/子项的影响 对数据库中的依赖项/子项的影响 Cascade 删除实体 删除实体 ClientSetNull 外键属性 ...
- 深入理解 EF Core:使用查询过滤器实现数据软删除
原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...
- ef core实现无感知软删除
很多web程序一般的偶不会设计真的物理删除了. 基本上都是在在数据库加一个标记,就得当作已经删除了.同时在查询的时候,过滤已经标记删除的数据 ef core实现软删除是非常简单的,直接在OnModel ...
- EF Core 新特性——Owned Entity Types
Owned Entity Types 首先owned entity type是EF Core 2.0的新特性. 至于什么是owned entity types,可以先把他理解为EF Core官方支持的 ...
随机推荐
- Maximum Size Subarray Sum Equals k LT325
Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If t ...
- Oracal 学习之用户角色创建分配表空间 给角色分配权限
//创建角色inspur 密码为inspur,默认的表空间为USERS create user inspur identified by inspur default tablespace USERS ...
- Java ClassLoad详解
Java ClassLoad详解 类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK 1. ...
- JNI,RegisterNative参数解析
Register native method - 数据类型和method descriptor 使用JNI时,为了使得虚拟机可以找到在C/C++ code中定义的native方法,有两种机制可以用,一 ...
- Linux运维之docker虚拟化部署nginx
一.Docker的概念 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱 ...
- Django的开始
一 浏览器相关知识 http:只有依赖一回,属于短链接,不会报错客户端的信息. 浏览器相当于一个客户端,客户端的链接 服务端:socket服务端,起服务监听客户端的请求. import socket ...
- 2019.01.21 bzoj2441: [中山市选2011]小W的问题(树状数组+权值线段树)
传送门 数据结构优化计数菜题. 题意简述:给nnn个点问有多少个www型. www型的定义: 由5个不同的点组成,满足x1<x2<x3<x4<x5,x3>x1>x2 ...
- 219.01.19 bzoj3252: 攻略(长链剖分+贪心)
传送门 长链剖分好题. 题意:给一棵带点权的树,可以从根节点到任一叶节点走kkk次,走过的点只能计算一次,问kkk次走过的点点权值和最大值. 思路: 考虑将整棵树带权长链剖分,这样链与链之间是不会重复 ...
- matlab 设定坐标比例
figure() u=-0.1:0.005:0.1; v=-0.1:0.005:0.1; [x,y]=meshgrid(u,v); z=sin(x-y)./abs(x)+abs(y); surf(x, ...
- 交换机的Access口与Trunk口
基本概念 Access类型的端口只能属于1个VLAN,一般用于连接计算机的端口:Trunk类型的端口可以允许多个VLAN通过,可以接收和发送多个VLAN的报文,一般用于交换机之间连接的端口: 处理流程 ...