在上一篇文章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