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”.
还有一种设置默认值的做法,你可以在实体的构造函数中设置默认值.构造函数在每个实体被创建时会调用,包括从数据库实例化这些实体时,不过你得小心处理,不要重写数据库里之前保存的数据.
Entity Framework 6 Recipes 2nd Edition(12-7)译 -> 设定默认值的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- Entity Framework 6 Recipes 2nd Edition(12-1)译 -> 当SaveChanges( ) 被调用时执行你的代码
第12章定制EF 在本章的小节里,定制实体对象和EF处理的一些功能.这些小节将涵盖很多”幕后”的事情,能让你的代码更加统一解决一些事情,比如用一个业务规则中心统一地为实体执行验证. 本章开始的小节,将 ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪
9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...
- Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询
问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...
- Entity Framework 6 Recipes 2nd Edition(13-9)译 -> 避免Include
问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...
- Entity Framework 6 Recipes 2nd Edition(目录索引)
Chapter01. Getting Started with Entity Framework / 实体框架入门 1-1. A Brief Tour of the Entity Framework ...
- Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
- Entity Framework 6 Recipes 2nd Edition(13-2)译 -> 用实体键获取一个单独的实体
问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...
随机推荐
- 火焰图分析openresty性能瓶颈
注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...
- Web Api 入门实战 (快速入门+工具使用+不依赖IIS)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...
- Mysql事务探索及其在Django中的实践(一)
前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...
- Eclipse中启动tomcat报错java.lang.OutOfMemoryError: PermGen space的解决方法
有的项目引用了太多的jar包,或者反射生成了太多的类,异或有太多的常量池,就有可能会报java.lang.OutOfMemoryError: PermGen space的错误, 我们知道可以通过jvm ...
- .NET Core的日志[3]:将日志写入Debug窗口
定义在NuGet包"Microsoft.Extensions.Logging.Debug"中的DebugLogger会直接调用Debug的WriteLine方法来写入分发给它的日志 ...
- 【开源】.Net 分布式服务中心
分布式服务中心 开源地址: http://git.oschina.net/chejiangyi/Dyd.BaseService.ServiceCenter 当垂直应用越来越多,应用之间交互不可避免,将 ...
- Dynamics CRM 之ADFS 使用 WID 的独立联合服务器
ADFS 的使用 WID 的独立联合服务器适用于自己的测试环境,常用的就是在虚机中使用. 拓扑图如下: wID:联合身份验证服务配置为使用 Windows 内部数据库
- 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比
C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...
- 15个C++项目列表
实验楼上有很多C++的实战项目,从简单到进阶,学习每个项目都可以掌握相应的知识点. 如果你还是C++新手的话,那么这个C++的项目列表你可以拿去练手实战开发,毕竟学编程动手实践是少不了的! 如果你不知 ...
- 在Linux虚拟机下配置jdk的环境变量
1.到Oracle公司的官网里下载好jdk,网址 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133 ...