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把修改保存到数据库.