在 ABP vNext 中编写仓储单元测试的问题一则

一、问题

新项目是基于 ABP vNext 框架进行开发的,所以我要求为每层编写单元测试。在同事为某个仓储编写单元测试的时候,发现了一个奇怪的问题。他的对某个聚合根的 A 字段进行了更新,随后对某个导航属性 B 也进行了变更,最后通过仓储提供的 UpdateAsync() 方法对变更的数据进行持久化。

结果再次查出来的时候,发现聚合根的 A 字段倒是更新了,但是导航属性 B 的内部字段没有进行变更。例如在下面的实例当中,聚合根的 Name 字段变更成功,但是导航属性的 Street 字段变更失败了。

640?wx_fmt=gif

二、原因

数据没有更新到,说明问题肯定出在 UpdateAsync 方法内部,通过打断点单步步入之后,也没发现有什么奇怪的地方,是使用的 ABP vNext 提供的默认仓储实现。

又在想是否跟实体追踪有关,然后看同事写得单元测试代码,发现他是先使用的 GetAsync() 方法获取到实体,然后手动变更了实体的属性。变更完成之后,通过仓储提供的 UpdateAsync() 方法进行更新。

看了很久发现它们并不是公用的一个工作单元,这就导致 GetAsync() 和 UpdateAsync() 方法内部得到的 DbContext 是不一样的。在 EF Core 内部针对这种情况,称之为 Disconnected entities 即断开连接的实体,这个时候需要用户手动 Attch 追踪导航属性。

三、解决

所以有两种解决办法,第一种方法是保证使用 GetAsync() 和 UpdateAsync() 方法时,它们都处于一个工作单元下,例如下面的伪代码。

private readonly IUnitOfWorkManager _uowMgr;
private readonly IRepository<TestUser, Guid> _repository;[Fact]
public async Task Resolve1()
{var entityId = Guid.NewGuid();await _repository.InsertAsync(new TestUser{Id = entityId,Name = "张三",Address = new TestUserAddress{City = "成都市",Street = "春熙路"}});using (var outerUow = _uowMgr.Begin()){var entity = await _repository.GetAsync(entityId);entity.Name = "李四";entity.Address.Street = "琴台路";await _repository.UpdateAsync(entity);await outerUow.CompleteAsync();}var result = await _repository.GetAsync(entityId);result.Name.ShouldBe("李四");result.Address.Street.ShouldBe("琴台路");
}

640?wx_fmt=png

第二种方法变动则要大一些, 导航属性没有更新的根本原因,是因为在第二个工作单元中没有追踪到这个属性,你只需要手动附加该导航属性即可。在下面的例子中,我们重写了 UpdateAsync() 方法,手动跟踪导航属性,也能够达到上述效果。

640?wx_fmt=png

四、参考资料

  • StackOverflow - Entity Framework disconnected graph and navigation property

  • MSDN - Disconnected entities

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP协议——三次握手与四次关闭

1. TCP协议基础 网络编程基础见&#xff0c;传送门 TCP是面向连接的&#xff0c;无论哪一方向另一方发送数据之前&#xff0c;都必须先在双方之间建立一条连接。 在TCP/IP协议中&#xff0c;TCP协议提供可靠的连接服务&#xff0c;连接是通过三次握手进行初始化的。 三次握手…

TCP协议——流量控制和拥塞控制

** 一、流量控制 ** 1.1 什么是流量控制 Sender won’t overflow receiver’s buffer by transmitting too much, too fast. &#xff08;防止发送方发的太快&#xff0c;耗尽接收方的资源&#xff0c;从而使接收方来不及处理&#xff09; 1.2 流量控制的一些知识点 &#x…

征集.NET中国峰会议题

月初做的调查《》&#xff0c;参与人数576人&#xff0c;愿意参与分享.NET Core经验的142人&#xff0c;今天发起分会场主题演讲和闪电演讲议题.2014年微软组织成立.NET基金会&#xff0c;微软在成为主要的开源参与者的道路上又前进了一步。2014年以来已经有众多知名公司加入.N…

TCP协议——粘包与拆包

TCP的基础 TCP协议基础&#xff0c;传送门 TCP协议流量控制&#xff0c;传送门 1.1 什么是TCP粘包/拆包 TCP是个“流”协议&#xff0c;所谓流&#xff0c;就是没有界限的一串数据。大家可以想想河里的流水&#xff0c;是连成一片的&#xff0c;其间并没有分界线。TCP底层并…

你的通勤时间都去哪了?

大家好&#xff0c;我是Z哥。今天我来唠叨一下。最近无意间看到一份报告&#xff0c;关于我们职场人士上下班通勤时间的。有时候想想也挺无奈的&#xff0c;我们越想去发达一些的城市打拼&#xff0c;反而越被通勤这种琐碎的事情给耽误更多的奋斗时间。但是没办法&#xff0c;在…

规模化敏捷必须SAFe

引子&#xff1a;规模化敏捷转型从来不是一件容易的事情。当只有1-2个敏捷团队进行协同的时候&#xff0c;计划和工作同步是可控的。团队和产品负责人互相聊一聊&#xff0c;基本就能搞清楚需要做什么&#xff0c;一个简单的SOS架构&#xff08;Scrum of Scrums&#xff09;就能…

http1.0 http1.1 http2 之间的区别

一、HTTP基础 1.1 HTTP定义 HTTP协议&#xff08;HyperTextTransferProtocol&#xff0c;超文本传输协议&#xff09;是用于从WWW服务器传输超文本到本地浏览器的传输协议。 1.2 HTTP发展史 1.3 HTTP1.0 早先1.0的HTTP版本&#xff0c;是一种无状态、无连接的应用层协议。 …

漫画:程序员一时单身一时爽,一直单身...有点惨

1妹子没吃早饭早啊敲哥&#xff0c;你在吃早饭啊嗯啊&#xff0c;你吃了吗&#xff1f;没呢&#xff0c;早上实在是太赶了&#xff0c;没来得及嗯...那我还是换个地方吃吧免得馋着你。。。2代码重要还是女朋友重要女朋友能哄好&#xff0c;代码能哄好吗&#xff1f;写代码是赚钱…

AutoMapper多个对象映射到一个Dto对象

一、定义源映射对象为了体现AutoMapper映射特性&#xff0c;在SocialAttribute中的Name属性没有定义在People中&#xff0c;People的Ear属性也不存在与SocialAttribute和PhysicalAttribute中。代码如下&#xff1a;二、注入AutoMapper例子中使用的IOC容器是Autofac&#xff0c;…

cookie 与 session

1 背景介绍 什么是会话&#xff1f; 用户打开一个浏览器, 点击多个超链接, 访问服务器多个web资源, 然后关闭浏览器, 整个过程称之为一个会话。我们知道&#xff0c;HTTP协议是一种"无状态"协议&#xff0c;客户浏览器与服务器建立连接&#xff0c;发出请求&#x…

Java写一个简单的静态文件的HTTP服务器(基于Socket)

** 一、实现思路 ** 1、使用 ServerSocket 监听某一端口&#xff0c;然后等待连接获取 Socket对象。 2、创建一个类 HttpServer 继承 java.lang.Thread 类&#xff0c;重写 run()方法&#xff0c;执行浏览器请求。 3、获得浏览器请求&#xff0c;解析资源文件路径。 4、读…

asp.net core 使用HttpClientFactory Polly实现熔断降级

前言在NET Core2.1后也是增加更新了很多东西,当然HttpClientFactory更新中的一部分.虽然说HttpClient这个实现了disposable,但使用它的时候用using包装块的方式通常不是最好的选择。处理HttpClient,底层socket套接字不会立即释放。该HttpClient类是未多个请求重复使用而创建的。…

Azure Application Insights REST API使用教程

本文是Azure Application Insights REST API的简单介绍&#xff0c;并会包含一个通过Python消费API的示例/小工具。新加入的team中的一项工作是制作日常的运维报表&#xff0c;制作方式是手工前往portal.azure.com&#xff0c;在网页中多次执行不同的查询语句、导出excel&#…

用Java Socket实现SMTP邮件发送

目录&#xff1a; 1、邮件基础概念2、Java Mail API介绍3、收发邮件代码示例 PS&#xff1a;如果你想直接拿代码用&#xff0c;可以直接跳到第3部分。 ** 一、邮件基础概念 ** 1.1 邮件服务器和电子邮箱 要在Internet上提供电子邮件功能&#xff0c;必须有专门的电子邮件…

微软开源新字体Cascadia Code,源于Windows Terminal

微软开源了一套新的字体 Cascadia Code。Cascadia Code 是微软在 5 月份的 Build 大会上宣布推出的等宽字体&#xff0c;微软介绍它是与新的终端 Windows Terminal 一起开发的&#xff0c;官方建议将其与终端应用和 VS、VS Code 等文本编辑器一起使用。Cascadia Code 为命令行和…

进程间通讯的7种方式

1、常见的通信方式 管道pipe&#xff1a;管道是一种半双工的通信方式&#xff0c;数据只能单向流动&#xff0c;而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。命名管道FIFO&#xff1a;有名管道也是半双工的通信方式&#xff0c;但是它允许无亲缘…

官宣!VS Code Python 全新功能在 PyCon China 全球首发!

北京时间 2019 年 9 月 21 日&#xff0c;PyCon China 2019 在上海举行。在下午的演讲中&#xff0c;来自微软开发工具事业部的资深研发工程师在演讲中&#xff0c;我们看到了 Azure Notebook 与 VS Code 对 Python 的强大的支持。然而&#xff0c;鱼和熊掌似乎不可兼得。Jupyt…

什么是CDN

一、cdn简介 CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其目的是通过在现有的internet中增加一层新的网络架构&#xff0c;将网站的内容发布到最接近用户的网络边缘&#xff0c;使用户可以就近取得所需的内容&#xff0c;提高用户访问网站的响应速度。…

高性能最终一致性框架Ray之基本概念原理

一、Actor介绍Actor是一种并发模型&#xff0c;是共享内存并发模型的替代方案。共享内存模型的缺点&#xff1a;共享内存模型使用各种各样的锁来解决状态竞争问题&#xff0c;性能低下且让编码变得复杂和容易出错。共享内存受限于单节点的服务器资源限制。Actor模型的优点&…

漫画:程序员带娃日常(1)

我是一名IT界资深人士做过乙方苦哈哈做过甲方做过项目、搞点管理做过培训、也上台演讲不过现在最大挑战、交期最长的项目是。。。带 娃娃子啊&#xff0c;爸爸也是第一次当爸爸&#xff0c;要请你多多指教啦&#xff01;1“小刘&#xff0c;把这个需求细化一下。”“兄弟们&…