Entity Framework:如果允许模型处于非法状态,在某些场景下,记得清空DbContext

背景

之前写过两篇文章介绍模型的合法性:

  1. DDD:关于模型的合法性,Entity.IsValid()合理吗?
  2. .NET:关于数据模型、领域模型和视图模型的一些思考

今天讨论的问题其实是关于“主键映射”的,只是其中还涉及一种决策:“允许模型处于非常状态”。

测试代码

 1         public static void Do()
2 {
3 Database.SetInitializer<MyDbContext>(new DropCreateDatabaseAlways<MyDbContext>());
4
5 using (var context = new MyDbContext())
6 {
7 /****************添加一个Note*****************/
8 var note = new Note { Name = "合法名字" };
9 context.Set<Note>().Add(note);
10 context.SaveChanges();
11 /****************添加一个Note*****************/
12
13 try
14 {
15 /****************让Note处于非法状态*****************/
16 var firstNote = context.Set<Note>().First();
17 firstNote.Name = "非法名称";
18 if (firstNote.Name == "非法名称")
19 {
20 throw new InvalidOperationException("非法名称");
21 }
22 /****************让Note处于非法状态*****************/
23 }
24 catch
25 {
26 //这里会出现BUG,显示的还是非法名字。
27 Console.WriteLine(context.Set<Note>().First().Name);
28
29 //清空DbContext以后就对了。
30 foreach (var entity in context.ChangeTracker.Entries())
31 {
32 entity.State = EntityState.Detached;
33 }
34 Console.WriteLine(context.Set<Note>().First().Name);
35 }
36 }
37 }

分析

第一个输出之所以不是期望的结果是因为EntityFramework内置了主键映射模式,内存状态还是处于非法状态,虽然First会导致一次数据库往返。

第二个输出之所以正确是因为清空了主键映射,这样会导致重新用数据库的内容填充主键映射。

结论

出现异常最好终止线程或程序的执行,上边这种BUG是因为使用了一种异常反模式:“把异常作为正常的逻辑处理流程”。

备注

这个错误我犯过,后来的朋友也犯过。

Entity Framework:如果允许模型处于非法状态,在某些场景下,记得清空DbContext的更多相关文章

  1. DDD:再谈:实体能否处于非法状态?

    背景 实体能否处于非法状态吗?如果实体只承担其作为实体的职责,我不认为实体可以处于非法状态,如果您将实体在不同的分层之间传递,如:UI->Application->Domain-Data, ...

  2. Entity Framework二、 模型优先 ,ObjectContext类

    https://www.cnblogs.com/ejiyuan/archive/2009/05/27/1490786.html 1.ObjectContext 封装.NET Framework和数据库 ...

  3. Entity Framework入门教程(5)---EF中的持久化场景

    EF中的持久性场景 使用EF实现实体持久化(保存)到数据库有两种情况:在线场景和离线场景. 1.在线场景 在线场景中,context是同一个上下文实例(从DbContext派生),检索和保存实体都通过 ...

  4. Programming Entity Framework 翻译(1)-目录

    1. Introducing the ADO.NET Entity Framework ado.net entity framework 介绍 1 The Entity Relationship Mo ...

  5. Entity Framework Core 生成跟踪列

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

  6. Entity Framework 6 多对多增改操作指南

    问题描述 在很多系统中,存在多对多关系的维护.如下图: 这种多对多结构在数据库中大部分有三个数据表,其中两个主表,还有一个关联表,关联表至少两个字段,即左表主键.右表主键. 如上图,其中的Suppli ...

  7. Entity Framework 杂碎

    其实看图很简单,database first和model first都是通过 data model创建的edmx文件,只不过model first模块可以自己根据需要创建和修改实体,显得更加灵活. c ...

  8. Entity Framework系列教程汇总

    翻译自http://www.entityframeworktutorial.net/,使用EF几年时间了,一直没有系统总结过,所以翻译这一系统文章作为总结,由于英语功底有限,翻译的可能有些问题,欢迎指 ...

  9. Entity Framework Core(EF Core) 最简单的入门示例

    目录 概述 基于 .NET Core 的 EF Core 入门 创建新项目 更改当前目录 安装 Entity Framework Core 创建模型 创建数据库 使用模型 基于 ASP.NET Cor ...

随机推荐

  1. C#-面向对象的多态思想 ---ShinePans

    总结: 多态是面向对象的核心.---------能够理解为一个方法,多种实现, 在这里能够用虚方法,抽象类,接口能够实现多态 1.首先利用接口来实现多态: 接口相当于"功能,"接口 ...

  2. VisualStudio2012轻松把JSON数据转换到POCO的代码

    原文:VisualStudio2012轻松把JSON数据转换到POCO的代码       在Visual Studio 2012中轻松把JSON数据转换到POCO的代码,首先你需要安装Web Esse ...

  3. pyqt学习总结

    一.学习来由: 近期一段时间,应朋友的须要,完毕一款抓取软件.一般而言,python是我比較熟悉的语言,又有丰富的抓取和解析模块,所以果断选择之. 而这远远不是重点,后台程序在工作做常常写,所以比較熟 ...

  4. VirtualBox更改虚拟机磁盘VDI的大小

    流程虚拟机中使用,有时会遇到磁盘大小是不够的,假设一套"动态分配的内存".通过下面的方法来手动扩展磁盘空间. 1.启动CMD命令行.进入VirtualBox安装文件夹.例如 cd  ...

  5. 微软不也是从Altair Basic这丑小鸭长成白天鹅吗?

    微软不也是从Altair Basic这丑小鸭长成白天鹅吗? February 2015 如果你想要弄清楚初创企业是怎么一回事的话,其中一个非常有价值的尝试是去研究下那些获得巨大成功的公司,去分析下为什 ...

  6. C语言库函数大全及应用实例四

    原文:C语言库函数大全及应用实例四                                    [编程资料]C语言库函数大全及应用实例四 couble fmod (double x, dou ...

  7. Fedora21无法播放MP4[已解决]

    首先,安装安装rpmfusion源 http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-21.noarch.rpm ht ...

  8. hdu - 4979 - A simple math problem.(可反复覆盖DLX + 打表)

    题意:一种彩票共同拥有 N 个号码,每注包括 M 个号码,假设开出来的 M 个号码中与自己买的注有 R 个以上的同样号码,则中二等奖,问要保证中二等奖至少要买多少注(1<=R<=M< ...

  9. 批处理中set截取字符具体解释

    set截取字符具体解释  在批处理中,set的功能有点繁杂:设置变量.显示环境变量的名及值.做算术运算.等待用户的输入.字符串截取.替换字符串,是我们经常使用的命令之中的一个. 在字符串截取方面,新手 ...

  10. .NET简单企业应用

    <.NET简单企业应用>项目开发环境 项目开始,开发团队需要构建一套开发环境,主要包含:开发工具.代码管理/版本控制系统.任务和Bug管理系统和持续集成(CI)系统.本文主要列举项目开发中 ...