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

12-7. 设定默认值

问题

在把一个实体保存到数据库之前,设置该实体属性的默认值

解决方案

假设你有一个如Figure 12-9所示的表, 它保存采购订单(purchase order). 主键PurchaseOrderId是一个GUID,有订单创建时间,最后修改时间,和备注,而且备注列不再使用,设置成 “N/A”.因为不用该列,所以在实体里也没有对应的属性. 你想初始化PurchaseOrderId 列, 两个日期时间列, Paid列, 和 comments 列为默认值. 我们的模型如 Figure 12-10所示.

 

Figure 12-10. The model created from the PurchaseOrder table in Figure 12-9

 

 

Figure 12-9. The PurchaseOrder table with several columns that need default values

我们将举例说明三种不同的方法来设置默认值. 默认值不用动态计算,属性会在概念层被设置为默认值. 选择Paid 属性在属性窗口查看它的所有属性. 会看到它的默认值为false.

对于在运行时需要计算值的属性我们需要override   SaveChanges 事件.如Listing 12-7所示. 在这个事件里,如果对象的状态是 Added  ,我们把 PurchaseOrderId 的值设置为一个新的GUID,和设置CreateDate 和ModifiedDate 字段.

为说明在模型概念之外设置默认值,我们通过修改存储层为列设置默认值,这种方式对于某些没出现在模型里的属性是非常有用的.

. 接下来通过模型层设置属性默认值 :右击.edmx 文件➤打开方式 ➤ XML 编辑器. 在.edmx 文件里SSDL节的<Property>标签下,为Comment属性添加DefaultValue="N/A".

Listing 12-7. 通过Override SaveChanges 事件设置默认值

    class Program

    {

        static void Main(string[] args)

        {

            RunExample();

        }

        static void RunExample()

        {

            using (var context = new EFRecipesEntities())

            {

                context.PurchaseOrders.Add(

                new PurchaseOrder { Amount = 109.98M });

                context.PurchaseOrders.Add(

                new PurchaseOrder { Amount = 20.99M });

                context.PurchaseOrders.Add(

                new PurchaseOrder { Amount = 208.89M });

                context.SaveChanges();

            }

            using (var context = new EFRecipesEntities())

            {

                Console.WriteLine("Purchase Orders");

                foreach (var po in context.PurchaseOrders)

                {

                    Console.WriteLine("Purchase Order: {0}",

                    po.PurchaseOrderId.ToString(""));

                    Console.WriteLine("\tPaid: {0}", po.Paid ? "Yes" : "No");

                    Console.WriteLine("\tAmount: {0}", po.Amount.ToString("C"));

                    Console.WriteLine("\tCreated On: {0}",

                    po.CreateDate.ToShortTimeString());

                    Console.WriteLine("\tModified at: {0}",

                    po.ModifiedDate.ToShortTimeString());

                }

            }

        }

    }

    public partial class EFRecipesEntities

    {

        public override int SaveChanges()

        {

            var changeSet = this.ChangeTracker.Entries().Where(e => e.Entity is PurchaseOrder);

            if (changeSet != null)

            {

                foreach (var order in changeSet.Where(c => c.State == System.Data.Entity.

                EntityState.Added).Select(a => a.Entity as PurchaseOrder))

                {

                    order.PurchaseOrderId = Guid.NewGuid();

                    order.CreateDate = DateTime.UtcNow;

                    order.ModifiedDate = DateTime.UtcNow;

                }

                foreach (var order in changeSet.Where(c => c.State == System.Data.Entity.

                EntityState.Modified).Select(a => a.Entity as PurchaseOrder))

                {

                    order.ModifiedDate = DateTime.UtcNow;

                }

            }

            return base.SaveChanges();

        }

}

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

Purchase Orders

Purchase Order: 1b4df3c6-6f72-4c6b-9ce2-331bad509be5

Paid: No

Amount: $208.89

Created On: 3:15 PM

Modified at: 3:15 PM

Purchase Order: c042f045-38af-4bfc-93c0-a870ffd36195

Paid: No

Amount: $20.99

Created On: 3:15 PM

Modified at: 3:15 PM

Purchase Order: 223faf4a-e128-4f5a-8dee-b9b104ed43b7

Paid: No

Amount: $109.98

Created On: 3:15 PM

Modified at: 3:15 PM

原理

我们演示了三种不同的设置默认值的方法. 一个属性的默认值是静态的而且属性被实体所暴露,我们可以通过设计器设置.如Paid属性,而且把它的默认值设置为false是非常合适的,因为新的订单一般还没付款.对于那些需要动态计算的,如CreateDate, ModifiedDate, 和PurchaseOrderId属性,我们   override   SaveChanges 事件来计算这些值并设置为它们的默认值再保存到数据库.最后, 对于没有出现在模型表面上的属性而且又需要一个静态的默认值, 我们可以使用在存储层用Default Value 属性来设置默认值, 在本小节,我们就是在存储层把  comments 的默认值设置为“N/A”.

还有一种设置默认值的做法,你可以在实体的构造函数中设置默认值.构造函数在每个实体被创建时会调用,包括从数据库实例化这些实体时,不过你得小心处理,不要重写数据库里之前保存的数据.

 

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

 

 

posted @ 2016-01-27 23:36  kid1412  阅读(453)  评论(0编辑  收藏  举报