加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

在Entity Framework中使用存储过程(三):逻辑删除的实现与自增

发布时间:2020-12-16 09:07:06 所属栏目:asp.Net 来源:网络整理
导读:本篇文章通过实例的方式,讨论两个在EF使用存储过程的主题:如何通过实体和存储过程的映射实现逻辑删除;对于具有自增长类型主键的数据表,在进行添加操作的时候如何将正确的值反映在实体对象上。 目录 一、基于逻辑删除的数据表和存储过程定义 二、如何过滤

本篇文章通过实例的方式,讨论两个在EF使用存储过程的主题:如何通过实体和存储过程的映射实现逻辑删除;对于具有自增长类型主键的数据表,在进行添加操作的时候如何将正确的值反映在实体对象上。

目录
一、基于逻辑删除的数据表和存储过程定义
二、如何过滤逻辑删除记录
三、具有自增长列的存储过程定义
四、通过Result Columns Binding将结果集的列于实体属性进行绑定

一、基于逻辑删除的数据表和存储过程定义

较之物理删除(记录彻底从数据表中清除掉),逻辑删除则继续保留该数据,只是为之进行一个删除标记,表明该记录已经被“删除”了。比如通过下面的SQL,我创建了一个简单的表T_CONTACT表,其中BIT类型的字段IS_DELETED就为这个“删除标记”。

   1: CREATE TABLE T_CONTACT
   3:  [ID]             VARCHAR(50)     PRIMARY KEY,
   5:  [IS_DELETED]     BIT             NULL
    
   2: (@p_id VARCHAR(50))
   4: BEGIN
   6:     SET       IS_DELETED = 1
   8: END 

二、如何过滤逻辑删除记录

打开VS,通过导入该数据表和CUD存储过程创建.edmx模型,同时修改概念模型实体名称(比如T_CONTACT改成Contact)和属性名称。并删除属性IS_DELETED,最终得到如右图所示的.edmx模型。然后为Contact实体映射CUD存储过程和相关参数,其中删除操作的存储过程已经定义在上面。

然后,你需要考虑这样一个问题:由于我们进行的是逻辑删除,被“删除”的记录依然存储于数据库中。当你进行数据查询的时候,如果没有显式设置IS_DELETED=0为筛选条件的情况下,所有被“删除”的记录依然会被返回。进一步地讲,由于我们在.edmx模型的概念实体Contact中,已经将IS_DELETED删除掉了,所以我们在程序中不可能设置这样一个额外的筛选条件。

实际上EF为你考虑到了这一点,你可以在直接通过EF设计器设置这样一个筛选条件。在当前实体被选中的情况下,进入Mapping Details界面,你会发现在于数据库表的映射中具有一个<Add a Condition>的下拉框,通过该下拉框你可以设置基于数据库表相关列的筛选条件。如下图所示,我设置了筛选条件“IS_DELETED = 0”来过滤掉被逻辑删除的记录。

基于上面的设置编写如下的代码,先添加3条Contact记录,然后将它们删除。并在删除前后根据ID获取对应记录,打印出来以验证上面设计的筛选条件是否真的有效。

2: {
   4:         Guid.NewGuid().ToString(),1)" id="lnum5">   5:         Guid.NewGuid().ToString(),1)" id="lnum6">   6:         Guid.NewGuid().ToString() };
   8:     {
  10:         Contact contact2 = Contact.CreateContact(contractIds[1],1)">"Li Si");
  12:         context.Contacts.AddObject(contact1);
  14:         context.Contacts.AddObject(contact3);
  16:? 
  18:         foreach(var contact in context.Contacts.Where(c=>contractIds.Contains(c.ID)))
  20:             Console.WriteLine("{0}: {1}",contact.ID,contact.Name);
  22:         foreach (var contact in context.Contacts.Where(c => contractIds.Contains(c.ID)))
  24:             context.Contacts.DeleteObject(contact);
  26:         context.SaveChanges();
  28:         Console.WriteLine("After Delete...");
  30:         {
  32:         }
  34: }

下面是输出结果,可见被删除的记录真的不曾出现在查询结果中。

2: 4032d301-80cb-4e6d-a3e7-f5560e918b4a: Li Si
   4: dbadfef9-d6d2-466b-8eae-392f1d731c14: Wang Wu
   3:     [ID]            INT IDENTITY(1,1)       4:     [NAME]          NVARCHAR(50)            5:     [IS_DELETED]    BIT                     6: )

如果你希望真正的ID能够返回给被添加的Contact对象,在存储过程中完成添加操作后,应该通过SELECT语句将对应的真实ID返回,这样的存储过程应该这样来写:

2: @p_name NVARCHAR(50)
VALUES(    @p_name,0)
   8:     SELECT [ID]
  10:     WHERE [ID] = SCOPE_IDENTITY()
   4:     {
   6:         context.Contacts.AddObject(contact);
   8:         Console.WriteLine(   9:? 
  11:         context.Contacts.AddObject(contact);
  13:         Console.WriteLine(  14:? 
  16:         context.Contacts.AddObject(contact);
  18:         Console.WriteLine(  19:     }
   1: 10: Zhang San
   3: 12: Wang Wu

在Entity Framework中使用存储过程(一):实现存储过程的自动映射
在Entity Framework中使用存储过程(二):具有继承关系实体的存储过程如何定义?
在Entity Framework中使用存储过程(三):逻辑删除的实现与自增长列值返回
在Entity Framework中使用存储过程(四):如何为Delete存储过程参数赋上Current值?
在Entity Framework中使用存储过程(五):如何通过存储过程维护多对多关系?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读