Entity Framework 6 Recipes 2nd Edition(9-5)译->删除一个断开的实体
9-5. 删除一个断开的实体
问题
我们要把一个把WCF上取回的对象做上删除的标志.
解决方案
假设我们有如Figure 9-5所示实体的支付与票据的模型.

Figure 9-5. 一个支付与票据的模型
我们的模型展示了支付记录与票据的关系。在应用程序中,我们用客户端与用WC封装EF数据访问交互
. 在我们的例子中,我们要用WCF服务删除Payment (支付)实体。为尽可能简单,我们创建一个WCF服务库并且定义模型:
1.右击解决方案,选择新项目,选择WCF ➤WCF服务库,并命名为:Recipe5
2. 右击Recipe5 项目➤添加➤新建项,选择“数据” ➤ ADO.NET 实体数据模型. 根据向导,添加 Invoice 和 Payment 表. 简单起见,我们删除了Invoice实体的导航属性Payments(在Invoice实体的Payments属性上右击,选择“从模型删除”)右击Payment 实体的TimeStamp 属性, 选择“属性”, 设置“并发模式”为Fixed. 这样会使TimeStamp做为并发控制,当删除或更新实体时,它的值将作为SQL语句的Where条件的一部分,3. 用Listing 9-27里的代码,改变IService1.cs文件里的服务定义.
Listing 9-27. The Service Contract for Our WCF Service
[ServiceContract]
public interface IService1
{
[OperationContract]
Payment InsertPayment();
[OperationContract]
void DeletePayment(Payment payment);
}
4. 在Service1.cs文件中, 实现服务,如Listing 9-28所示.
Listing 9-28. The Implementation of Our Service Contract
public class Service1 : IService1
{
public Payment InsertPayment()
{
using (var context = new EFRecipesEntities())
{
//删除之前的测试数据
context.Database.ExecuteSqlCommand("delete from chapter9.payment");
context.Database.ExecuteSqlCommand("delete from chapter9.invoice");
var payment = new Payment
{
Amount = 99.95m,
Invoice = new Invoice { Description = "Auto Repair" }
};
context.Payments.Add(payment);
context.SaveChanges();
return payment;
}
}
public void DeletePayment(Payment payment)
{
using (var context=new EFRecipesEntities())
{
context.Entry(payment).State = EntityState.Deleted;
context.SaveChanges();
}
}
}
5. 为测试服务, 需要一个客户端. 在解决方案里添加一个新的控制台应用程序项目
. 客户端代码如Listing 9-29所示. 在WCF上右击,调试➤启动新实例,再在控制台项目上右击➤添加➤服务引用,然后添加对WCF的引用.
Listing 9-29. A Simple Console Application to Test Our WCF Service
class Program
{
static void Main(string[] args)
{
var client = new ServiceReference1.Service1Client();
var payment = client.InsertPayment();
client.DeletePayment(payment);
}
}
如果你在Main()方法首行代码前设置断点,然后调试,“逐语句”执行,可以看到WCF服务的执行
它是如何工作的
在本小节, 我们演示了客户端调用服务对断开连接的实体进行操作
.在客户端,我们用InsertPayment() 方法向数据库插入一个新的 payment. 该方法返回被插入的
payment. 当然 payment 返回给客户端后就从DbContext中断开连接.实际上DbContext可以在不同的进程里,甚至于在不同计算机上,
我们用DeletePayment() 方法来把数据库中的Payment删除 . 这个方法中 (见Listing 9-28), 我们调用DbContext 的Entry() 方法,并传递一个 Payment参数. 然后把Payment实体的属性设置为EntityState.Deleted,接着SaveChanges() 方法会生成一条删除的SQL语句,并把数据从数据库中删除. 因为我们用了外键关联, 并发属性TimeStamp是必需的,EF会在SQL的Where子句中使用到。
用这种方式解决迸发. 会遇到一个问题,当你的POCO类有一个或更多复合型属性时,因为复合类型,在EF里是被重视的,不能为null,简单和解决办法是:为复合类型创建一个虚拟的实例。如果你让复合类型为null,SaveChanges()方法将会抛出一个异常。
如果在多对1和0..1中使用一个独立关联,EF要求它们的实体键具有正确的值,以为修改和删除生成Where子句. 在我们例子里,如果在Invoice和Payment中有一个独立关联,我们需要给Invoice的InvoiceId导航设置正确的值,来关联Invoice实例.这样Where子句里将会包含PaymentId, TimeStamp, 和InvoiceId.
===================================================================
■■注意:当用EF实例一个N层架构时,应慎重地考虑是否用分配外键来关联相关的实体,独立关联比较难实现,并会使你的代码变得复杂. 对此EF团队的Arthur Vickers 发布的whats-the-deal-with-mapping-foreign-keys-using-the-entity-framework 博客,有个很好的解释.当然也欢迎你细读他的EF的其它文章.
=======================================================================
如果实体对象包含多个独立关联,设置它们就是件乏味的事,你可以简单地从数据库重新取回然后再删除,这样会使你代码简单些,但是当你从数据库重新取回,EF将重写这些实体间关系
, 当然你可以有NoTracking 选项关闭context 跟踪来解决.
如果本小节我们用独立关联的方式,为已经加载了Payment 实体做删除标志时,EF将会对Payment和相关联的Invoice做上删除标志。
同样地,结果的SQL名句的Where子句包含PaymentId, TimeStamp, and InvoiceId列。
在独立关联在删除实体的另一个选择是:预先加载相关联的实体,然后将整个对象图传给WCF或是Web API来进行删除。就我们的实例,我们可以预先加载Invoice和相关的Payment实体。如果我们要删除Payment实体,我们需要回传包含Invoice实体的整个对象给服务。不过这样会消费更多带宽有更多序列处处理的时间,所以它可能带来的好处还比不上消耗。
Entity Framework 6 Recipes 2nd Edition(9-5)译->删除一个断开的实体的更多相关文章
- Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新
因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...
- Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用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-2)译 -> 用实体键获取一个单独的实体
问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...
- Entity Framework 6 Recipes 2nd Edition(13-3)译 -> 为一个只读的访问获取实体
问题 你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现 解决方案 一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种 ...
- 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-5)译 -> 使POCO的修改追踪更高
问题 你正在使用POCO,你想提高修改跟踪的性能,同时使内存消耗更少.另外,你想通过EF的CodeFirst方式来实现. 解决方案 假设你有一个关于Account(帐户)和相关的Payments(支付 ...
- Entity Framework 6 Recipes 2nd Edition(13-8)译 -> 把昂贵的属性移到其它实体
问题 你想把一个昂贵的属性移到另一个实体,这样你就可以延迟加载当前这个实体.对于一个加载昂贵的而且很少用到的属性尤其有用. 解决方案 模型和上一节(Recipes 13-7)的一致,如Figure13 ...
- Entity Framework 6 Recipes 2nd Edition(13-9)译 -> 避免Include
问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...
随机推荐
- .NET面试题系列[8] - 泛型
“可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- Js new到底发生了什么
在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...
- 【SQLServer】【恢复挂起的解决方案】附加文件时候的提示“无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。 ”【数据库恢复】
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 先贴错误: 吐槽一下: 进入正题: 新建一个同名数据库 停止MSSQL服务 替换数据库文 ...
- load和initialize方法
一.load 方法什么时候调用: 在main方法还没执行的时候 就会 加载所有类,调用所有类的load方法. load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法. 在项目中使 ...
- C#多线程之基础篇3
在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...
- iOS逆向工程之KeyChain与Snoop-it
今天博客的主题是Keychain, 在本篇博客中会通过一个登陆的Demo将用户名密码存入到KeyChain中,并且查看一下KeyChain中存的是什么东西,把这些内容给导出来.当然本篇博客的重点不是如 ...
- WebGIS中等值线前端生成绘制简析
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值线是GIS制图中常见的功能,一般有两种思路:一种是先进行插 ...
- jQuery2.x源码解析(缓存篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 缓存是jQuery中的又一核心设计,jQuery ...
- 用MongoDB分析合肥餐饮业
看了<从数据角度解析福州美食>后难免心痒,动了要分析合肥餐饮业的念头,因此特地写了Node.js爬虫爬取了合肥的大众点评数据.分析数据库我并没有采用MySQL而是用的MongoDB,是因为 ...