实体代理类型
实体代理的用途就是识别实体的属性变更,并基于变更支持实体对象的 Insert/Update/Delete 操作。
因此实体对象提供的 Insert/Update/Delete 方法都要在实体代理类型上才能调用。
例如下面的示例:
using( DbContext db = DbConnManager.CreateAppDb("mysqltest") ) {
// 先删除之前测试可能遗留下来的数据
ModelX xx = db.Entity.CreateProxy<ModelX>();
xx.IntField = 1978;
xx.Delete();
// 插入一条记录,只给2个字段赋值
ModelX obj = db.Entity.CreateProxy<ModelX>();
obj.IntField = 1978;
obj.StringField = "abc";
obj.Insert();
// 检验刚才插入的数据行
ModelX m1 = (from x in db.Entity.Query<ModelX>() where x.IntField == 1978 select x).FirstOrDefault();
Assert.IsNotNull(m1);
Assert.AreEqual("abc", m1.StringField);
// m1 进入编辑状态
m1 = db.Entity.CreateProxy(m1);
m1.StringField = "12345";
int effect = m1.Update(); // 提交更新,WHERE过滤条件由主键字段决定
Assert.AreEqual(1, effect);
// 检验刚才更新的数据行
ModelX m2 = (from x in db.Entity.Query<ModelX>() where x.IntField == 1978 select x).FirstOrDefault();
Assert.IsNotNull(m2);
Assert.AreEqual("12345", m2.StringField);
// 删除数据行
ModelX obj2 = db.Entity.CreateProxy<ModelX>();
obj2.IntField = 1978;
effect = obj2.Delete();
Assert.AreEqual(1, effect);
// 检验删除结果
ModelX m3 = (from x in db.Entity.Query<ModelX>() where x.IntField == 1978 select x).FirstOrDefault();
Assert.IsNull(m3);
}
下面来看一个具体的示例,假如有一个实体:
它对应的代理类型结构是:
实体代理类型的产生
实体代理类型不需要在开发时编写,通常会在程序启动时自动产生,所以我们只需要知道它的存在以及用途就可以了。
基于Nebula开发的程序,会在程序启动时搜索打有 [assembly: ClownFish.Data.EntityAssembly] 标记的程序集, 并在其中搜索公开的实体类型,并为它们产生实体代理类型。 这个过程将会消耗一点时间,本文后面会介绍如何优化这部分时间的消耗。
实体的加载器类型
实体加载器类型的用途就是优化从数据库结果转实体对象的过程, 它用一种最优化的实现方式来减少这个过程的时间消耗, 大致思路就是自动生成一些机械但高效的代码来实现数据实体的加载过程。
这里还是以前面的 Category 类型举例,它对应的加载器类型的结构如下:
最终的性能提升可以查看:https://www.cnblogs.com/fish-li/archive/2012/07/17/ClownFish.html