• 使用主动实体(ActiveEntity)简化继承体系映射类的写操作


    在上一篇文章ORM中的继承关系映射全解中,演示了各种继承关系映射在NBear中实现示例,只不过,文中的示例对于一实体一具体表和一实体一扩展表方案下的子类的保存操作,需要用户手动save实体本身和其所有的父类对应的表。这多少有点不爽,因为,实体的用户是很难全都了解具体要save多少表的。为了解决这个问题,在最新的v2.1.6版中,为NBear新增了一个ActiveEntity类。ActiveEntity类最大的作用是封装了子类的插入,修改和删除操作。另外,ActiveEntity能够自动记录修改过的字段属性,因此,写数据库时,它只会Update真正修改过的实体的属性。在下面的示例中我们可以看到,如何使用ActiveEntity来简化前文介绍的实体继承中的一实体一具体表和一实体一扩展表示例。更多细节可以参考NBear中文用户手册

    --
    NBear v2.1.6 除了新增了本文探讨的ActiveEntity类,还有如下重要更新:

    1)Gateway.ExecuteProcedureXXX方法新增了对存储过程输出参数的支持
    2)修复了一个Gateway.Save中可能导致事务死锁的bug;
    --

    ActiveEntity包含如下成员:

    范型参数列表

    //Must give an IEntity when creating an instance
    public class ActiveEntity<IEntityType> where IEntityType : IEntity

    构造函数

    //Create an active entity based on an given entity
    public ActiveEntity(Gateway gateway, IEntityType obj) 
     
    //Create an active entity by given values of PKs, if no values are given, create an empty new active entity.
    public ActiveEntity(Gateway gateway, params object[] pkValues)  
     
    属性
     
    //The status of active entity, available values are ActiveEntityStatus.New and ActiveEntityStatus.Loaded.
    public ActiveEntityStatus Status
     
    //The entity can be read/write directly
    public IEntityType Entity

    公共方法 

    public void Save()
    public void Save(DbTransaction tran)
    public void Delete()
    public void Delete(DbTransaction tran)

    使用示例 

    1. 简单示例
     
    对于一个简单的Northwind中的Category实体,我们可以这样简化对其的Save和Delete操作:
     
       [Table("Categories")]
       public interface Category : IEntity
       {
           [PrimaryKey]
           int CategoryID { get; }
           string CategoryName { get; set; }
           string Description { get; set; }
           System.Byte[] Picture { get; set; }
       }
     
    --
               ActiveEntity<Category> obj = new ActiveEntity<Category>(gateway, 1);  //Load
               Assert.AreEqual(obj.Status, ActiveEntityStatus.Loaded);  //After Load, The status become Loaded
               string newCatName = Guid.NewGuid().ToString().Substring(0, 5);
               obj.Entity.CategoryName = newCatName;
               obj.Save();  //do saving, since only CategoryName is modified, the sql created and executed behind the framework only updates the CategoryName column of Categories table

               ActiveEntity<Category> obj2 = new ActiveEntity<Category>(gateway);  //create a new empty active entity for Category
               Assert.AreEqual(obj2.Status, ActiveEntityStatus.New);  //A new active entity's status is New before saving
               obj2.Entity.CategoryName = obj.Entity.CategoryName + "_new";
               obj2.Entity.Description = obj.Entity.Description;
               obj2.Entity.Picture = obj.Entity.Picture;
               obj2.Save();  //do inserting
               obj2.Delete();  //do deleting
     
    2. 简化一实体一具体表映射中的保存
     
    实体定义还是和一实体一具体表中的示例一样的代码,但是新的保存代码却大大简洁了:
     
           [Table("ParentTable")]
           public interface Parent : IEntity
           {
               [PrimaryKey]
               int ID { get; }
               string Name { get; set; }
           }
     
           [Table("AnotherParentTable")]
           public interface AnotherParent : IEntity
           {
               [PrimaryKey]
               int ID { get; }
               int Age { get; set; }
           }
     
           [Table("ChildTable")]
           public interface Child : Parent, AnotherParent
           {
               [PrimaryKey]
               new int ID { get; set; }
               DateTime Birthday { get; set; }
           }
     
    --
     
    //obj is a Child instance
     
    ActiveEntity<Child> activeObj = new ActiveEntity<Child>(gateway, obj);
    activeObj.Save();
     
    我们可以看到,当执行ActiveEntity<Child>.Save()时,它会自动执行等价于如下三条代码逻辑:
     
    Gateway.Save<Child>(obj, tran);
    Gateway.Save<Parent>(obj, tran);
    Gateway.Save<AnotherParent>(obj, tran);
     
    当然,即使实体有更复杂的继承关系,ActiveEntity也能自动保持一致的更新,这样就真正做到了对继承体系的更新和删除对用户是完全透明的。

  • 相关阅读:
    win7系统内网共享打印机设置
    VS中无法打开Qt资源文件qrc
    EF开发中EntityFramework在web.config中的配置问题
    【转】为什么你的硬盘容易坏?因为它转得实在是太快了
    AutoCAD批量导出点坐标
    【读书】《当我跑步时,我谈些什么》书评:我跑步时,只是跑着
    【C/C++】How to execute a particular function before main() in C?
    【gdb】A brief introduction on how to use gdb
    【Valgrind】How to check if we reading uninitialized memory in 10 min
    【Valgrind】How to check buffer overflow/underflow in 10 mins
  • 原文地址:https://www.cnblogs.com/teddyma/p/477512.html
Copyright © 2020-2023  润新知