12-8. 重新获取一个属性的原始值

问题

在实体保存到数据库之前,你想重新获取属性的原始值

解决方案

假设你有一个模型 (见 Figure 12-11) 表示一个员工( Employee),包含工资(salary)属性. 你有一个业务规则,规定一个员工的工资增长不能超过10%.在一个实体保存到数据库之前,你想验证这条规则,拿新的工资与原来的工资比较,看是否超过10%.

Figure 12-11. An Employee entity with the employee’s salary

为核实工资增长不超过10%,我们override SaveChanges 事件. 在该事件里,我们重新取得当前实体的原始值,如果新值超过原始值的10%,我们抛出一个异常,当然这个异常也会导致保存失败.

代码 Listing 12-8 展示了这些细节:

Listing 12-8. Overriding the SaveChanges Event to Enforce the Business Rule

class Program

{

static void Main(string[] args)

{

RunExample();

}

static void RunExample()

{

using (var context = new EFRecipesEntities())

{

var emp1 = new Employee { Name = "Roger Smith", Salary = 108000M };

var emp2 = new Employee { Name = "Jane Hall", Salary = 81500M };

context.Employees.Add(emp1);

context.Employees.Add(emp2);

context.SaveChanges();

emp1.Salary = emp1.Salary * 1.5M;

try

{

context.SaveChanges();

}

catch (Exception)

{

Console.WriteLine("Oops, tried to increase a salary too much!");

}

}

using (var context = new EFRecipesEntities())

{

Console.WriteLine();

Console.WriteLine("Employees");

foreach (var emp in context.Employees)

{

Console.WriteLine("{0} makes {1}/year", emp.Name,

emp.Salary.ToString("C"));

}

}

Console.WriteLine("Press any key to close...");

Console.ReadLine();

}

}

public partial class EFRecipesEntities

{

public override int SaveChanges()

{

var entries = this.ChangeTracker.Entries().Where(e => e.Entity is Employee && e.State ==

System.Data.Entity.EntityState.Modified);

foreach (var entry in entries)

{

var originalSalary = Convert.ToDecimal(

entry.OriginalValues["Salary"]);

var currentSalary = Convert.ToDecimal(

entry.CurrentValues["Salary"]);

if (originalSalary != currentSalary)

{

if (currentSalary > originalSalary * 1.1M)

throw new ApplicationException(

"Can't increase salary more than 10%");

}

}

return base.SaveChanges();

}

}

上述代码Listing 12-8输出结果如下:

Oops, tried to increase a salary too much!

Employees

Roger Smith makes $108,000.00/year

Jane Hall makes $81,500.00/year

原理

在override  SaveChanges里, 我们先获取状态为modified 的Employee 实体,接着挨个查看它们的Salary 属性的原始值与当前值.如果二者不相等且超过10%,我们就抛出一个ApplicationException异常. 否则, 我们就简单地调用DbContext 的  SaveChanges ,让EF把修改保存到数据库.

附:创建示例用到的数据库的脚本文件

Entity Framework 6 Recipes 2nd Edition(12-8)译 -> 重新获取一个属性的原始值的更多相关文章

  1. Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新

    因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...

  2. Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪

    9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...

  3. Entity Framework 6 Recipes 2nd Edition(12-7)译 -> 设定默认值

    12-7. 设定默认值 问题 在把一个实体保存到数据库之前,设置该实体属性的默认值 解决方案 假设你有一个如Figure 12-9所示的表, 它保存采购订单(purchase order). 主键Pu ...

  4. Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

    9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...

  5. Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询

    问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...

  6. Entity Framework 6 Recipes 2nd Edition(13-9)译 -> 避免Include

    问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...

  7. Entity Framework 6 Recipes 2nd Edition(目录索引)

    Chapter01. Getting Started with Entity Framework / 实体框架入门 1-1. A Brief Tour of the Entity Framework ...

  8. Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体

    第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...

  9. Entity Framework 6 Recipes 2nd Edition(13-2)译 -> 用实体键获取一个单独的实体

    问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...

随机推荐

  1. 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...

  2. OpenCV人脸识别Eigen算法源码分析

    1 理论基础 学习Eigen人脸识别算法需要了解一下它用到的几个理论基础,现总结如下: 1.1 协方差矩阵 首先需要了解一下公式: 共公式可以看出:均值描述的是样本集合的平均值,而标准差描述的则是样本 ...

  3. 【踩坑速记】二次依赖?android studio编译运行各种踩坑解决方案,杜绝弯路,总有你想要的~

    这篇博客,只是把自己在开发中经常遇到的打包编译问题以及解决方案给大家稍微分享一下,不求吸睛,但求有用. 1.大家都知道我们常常会遇到dex超出方法数的问题,所以很多人都会采用android.suppo ...

  4. Autofac - 方法注入

    方法注入, 其实就是在注册类的时候, 把这个方法也注册进去. 那么在生成实例的时候, 会自动调用这个方法. 其实现的方法, 有两种. 准备工作: public interface IAnimal { ...

  5. CSS中强悍的相对单位之em(em-and-elastic-layouts)学习小记

    使用相对单位em注意点 1.浏览器默认字体是16px,即1em = 16px,根元素设置如下 html{ font-size: 100%; /* WinIE text resize correctio ...

  6. React Native环境配置之Windows版本搭建

    接近年底了,回想这一年都做了啥,学习了啥,然后突然发现,这一年买了不少书,看是看了,就没有完整看完的.悲催. 然后,最近项目也不是很紧了,所以抽空学习了H5.自学啃书还是很无趣的,虽然Head Fir ...

  7. iOS在导航栏上居中显示分段控件(UISegmentedControl)

    UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:nil]; segmentedCont ...

  8. DevExpress - 使用 GaugeControl 标尺组件制作抽奖程序 附源码

    前不久,公司举办了15周年庆,其中添加了一个抽奖环节,要从在读学员中随机抽取幸运学员,当然,这个任务就分到了我这里. 最后的效果如下,启动有个欢迎页面,数据是来自Excel的,点击开始则上面的学号及姓 ...

  9. 如何编译Zookeeper源码

    1. 安装Ant Ant下载地址:http://ant.apache.org/bindownload.cgi 解压即可. 2. 下载Zookeeper源码包 https://github.com/ap ...

  10. CentOS上 Mono 3.2.8运行ASP.NET MVC4经验

    周一到周三,折腾了两天半的时间,经历几次周折,在小蝶惊鸿的鼎力帮助下,终于在Mono 3.2.8上运行成功MVC4.在此总结经验如下: 系统平台的版本: CentOS 6.5 Mono 3.2.8 J ...