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”.

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

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

Entity Framework 6 Recipes 2nd Edition(12-7)译 -> 设定默认值的更多相关文章

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

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

  2. Entity Framework 6 Recipes 2nd Edition(12-1)译 -&gt; 当SaveChanges( ) 被调用时执行你的代码

    第12章定制EF 在本章的小节里,定制实体对象和EF处理的一些功能.这些小节将涵盖很多”幕后”的事情,能让你的代码更加统一解决一些事情,比如用一个业务规则中心统一地为实体执行验证. 本章开始的小节,将 ...

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

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

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

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

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

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

  6. Entity Framework 6 Recipes 2nd Edition(13-9)译 -&gt; 避免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)译-&gt;用Web Api更新单独分离的实体

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

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

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

随机推荐

  1. popwindow设置背景半透明

    WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = 0.5f; //0.0-1.0 getWindow(). ...

  2. iOS全局调用的提示 没有网络 没有更多 等。。 短时间内自动消失

    本来想用SVProgressHUD 但是由于这个需求相对要简单 所以自己写了 下面上代码 .h 文件 #import <UIKit/UIKit.h> @interface HaveNoMo ...

  3. Windows环境中Openfire与Spark安装与配置指南

    安装软件: openfire3.9.3 spark2.6.3 安装环境: WindowsXP JDK1.6.0_21 Oracle 一.openfire安装 1.安装openfire3.9.3,下载地 ...

  4. winform中关于panel中滚动条和键盘事件几点体会

    最近在做winform开发中,遇到几个比较寄售的问题,通过上网查找计和自己琢磨,最终都圆满解决呢! 现在我将谈谈我在项目中遇到的问题集解决方案,以供大家参考! 一.就是我在使用键盘的keydown事件 ...

  5. IOS OC声明变量在@interface括号中与使用@property的区别(转载)

    刚开始接触OC再看别人写的代码的时候,常常困惑于人家在声明属性时的写法,总结出来有三中方式,不知道哪一种比较规范化,现在我把三种方式贴出来,然后再一一探讨每个方式声明属性的区别. 方式一:直接在@in ...

  6. 使用VBA进行JS加密的反混淆,还原JS代码。

    本文地址:http://www.cnblogs.com/Charltsing/p/JSEval.html 联系QQ:564955427 类似下面的代码是登陆 全国企业信用信息公示系统(安徽)(网址:h ...

  7. session的取代者:Json Web Tokens----在客户端存储登陆状态

    https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

  8. 知物由学 | 未来安全隐患:AI的软肋——故意欺骗神经网络

     本文由  网易云发布. “知物由学”是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道.“知物由学 ...

  9. spring IOC的常见几种以来注入的方式

    在spring ioc中有三种依赖注入,分别是:a.接口注入:b.setter方法注入:c.构造方法注入: 接口注入: public class ClassA { private InterfaceB ...

  10. ASP.NET Core 中的SEO优化(1):中间件实现服务端静态化缓存

    分享 最近在公司成功落地了一个用ASP.NET Core 开发前台的CMS项目,虽然对于表层的开发是兼容MVC5的,但是作为爱好者当然要用尽量多的ASP.NET Core新功能了. 背景 在项目开发的 ...