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

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

 

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

 

posted @ 2016-01-28 00:02  kid1412  阅读(466)  评论(0编辑  收藏  举报