当前位置:
首页 > 编程开发 > Objective-C编程 >
-
AOP的两个应用实体集更新DataEntityListUpdate、延迟加载Lazyload(上)
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
在FaibClass.Data中,有两个AOP的应用,它们分别是实体集更新(DateEntityListUpdate)、延迟加载 (LazyLoad),目前的DataEntity继承于ContextBoundObject,刚刚从网上看到ContextBoundObject的损耗非常大,但自己测试了一下,应该说影响不是很大,所以暂时不打算使用静态注入了。
注,两个AOP都采用Attribute--Property--Sink的结构,每个类的具体功能请查阅相关的技术资料。
一、实体集更新(DateEntityListUpdate)
在前台设置一个实体的属性,我们在更新整个实体集到数据库的时候,并不知道哪些属性更改过,如果全部更新,将造成不必要的浪费,所以引入了这个概念。如果我们不这样做,模型类的每个属性set后将添加一句代码AddUpdateColumn。
这里使用了.Net的消息链进行处理,因为实体类上还可能使用了其他的AOP。
EntityListUpdatableAttribute类
//*******************************************************************
// 模块:指示实体对象可被集合更新
// 日期:2009-7-29 1:05
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
using FaibClass.Data.Aspect;
namespace FaibClass.Data
{
/// <summary>
/// 指示实体的属性更改后,可以使用Update更新整个实体集,如果不指定此特性,实体的DataState无法置为Modified。
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class EntityListUpdatableAttribute : Attribute, IContextAttribute, IContextProperty
{
internal static string propertyName = "EntityListUpdatable";
/// <summary>
/// 构造属性。
/// </summary>
public EntityListUpdatableAttribute()
{
}
string IContextProperty.Name
{
get { return propertyName; }
}
void IContextProperty.Freeze(Context newContext)
{
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
return true;
}
void IContextAttribute.GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
IContextProperty interceptProperty = new EntityListUpdatableProperty();
ctorMsg.ContextProperties.Add(interceptProperty);
}
bool IContextAttribute.IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
{
if (ctx.GetProperty(propertyName) == null)
{
return false;
}
return true;
}
}
}
EntityListUpdatableProperty类
//*******************************************************************
// 模块:实体集更新的上下文属性
// 日期:2009-9-19 14:24:24
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Contexts;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 实体集更新的上下文属性。
/// </summary>
internal class EntityListUpdatableProperty : IContextProperty, IContributeObjectSink
{
void IContextProperty.Freeze(Context newContext)
{
}
string IContextProperty.Name
{
get { return EntityListUpdatableAttribute.propertyName; }
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
EntityListUpdatableProperty property =
newCtx.GetProperty(EntityListUpdatableAttribute.propertyName) as EntityListUpdatableProperty;
if (property == null)
{
return false;
}
return true;
}
IMessageSink IContributeObjectSink.GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
IMessageSink sink = new EntityListUpdatableSink(obj, nextSink);
return sink;
}
}
}
EntityListUpdatableSink类
//*******************************************************************
// 模块:用于处理属性修改后的消息接收器
// 日期:2009-9-19 14:24:12
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 用于处理属性修改后的消息接收器。
/// </summary>
internal class EntityListUpdatableSink : IMessageSink
{
private IMessageSink m_nextSink;
private MarshalByRefObject m_target;
private static object syncRoot = new object();
public EntityListUpdatableSink(MarshalByRefObject target, IMessageSink nextSink)
{
lock (syncRoot)
{
m_target = target;
m_nextSink = nextSink;
}
}
public IMessage SyncProcessMessage(IMessage msg)
{
IMethodReturnMessage returnedMessage;
HandleMessage(msg, false, out returnedMessage);
return returnedMessage;
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
IMethodReturnMessage returnedMessage;
HandleMessage(msg, true, out returnedMessage);
return m_nextSink.AsyncProcessMessage(msg, replySink);
}
public IMessageSink NextSink
{
get { return m_nextSink; }
}
private void HandleMessage(IMessage msg, bool IsAsync, out IMethodReturnMessage returnedMessage)
{
returnedMessage = null;
if (!IsAsync)
{
if (msg is IMethodCallMessage)
{
IMethodCallMessage mcm = (IMethodCallMessage)msg;
bool isFill = (bool)m_target.GetType().GetProperty("InnerIsFill", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(m_target, null);
bool isProperty = !isFill && ((mcm.MethodName.Length > 4 &&
mcm.MethodName.Substring(0, 4) == "set_" && mcm.MethodName != "set_InnerIsFill" &&
mcm.MethodName != "set_InnerDataState" &&
mcm.MethodName != "set_InnerData") || mcm.MethodName == "FieldSetter");
object oldvalue = null, newvalue = null;
MemberInfo minfo = null;
string propertyName = string.Empty;
//取原来的值
if (isProperty)
{
if (mcm.MethodName == "FieldSetter")
propertyName = mcm.InArgs[1].ToString();
else
propertyName = mcm.MethodName.Replace("set_", "");
minfo = Utility.GetMember(m_target.GetType(), propertyName);
if (minfo == null)
isProperty = false;
else if (minfo.IsDefined(typeof(DataColumnAttribute), true))
oldvalue = Utility.GetMemberValue(m_target, minfo, propertyName);
}
returnedMessage = (IMethodReturnMessage)m_nextSink.SyncProcessMessage(msg);
if (isProperty)
{
//新的值
newvalue = Utility.GetMemberValue(m_target, minfo, propertyName);
if (!newvalue.Equals(oldvalue))
{
//调用内部方法添加修改了的列
m_target.GetType().InvokeMember("AddUpdateColumn", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, m_target, new object[] { mcm.MethodName.Replace("set_", "") });
}
}
}
else
{
returnedMessage = (IMethodReturnMessage)m_nextSink.SyncProcessMessage(msg);
}
}
else
{
returnedMessage = null;
}
}
}
}
二、延迟加载(LazyLoad)
没有仔细研究过其他框架的延迟加载是怎么实现的,自己还是基于.Net的消息机制做了这个功能。
LazyLoadableAttribute类
//*******************************************************************
// 模块:延迟加载的属性
// 日期:2009-9-19 14:23:22
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
using FaibClass.Data.Aspect;
namespace FaibClass.Data
{
/// <summary>
/// 指示该实体中的子实体集、引用实体、引用属性可延迟载入。
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class LazyLoadableAttribute : Attribute, IContextAttribute, IContextProperty
{
internal static string propertyName = "LazyLoadable";
/// <summary>
/// 构造属性。
/// </summary>
public LazyLoadableAttribute()
{
}
string IContextProperty.Name
{
get { return propertyName; }
}
void IContextProperty.Freeze(Context newContext)
{
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
return true;
}
void IContextAttribute.GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
IContextProperty interceptProperty = new LazyLoadableProperty();
ctorMsg.ContextProperties.Add(interceptProperty);
}
bool IContextAttribute.IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
{
if (ctx.GetProperty(propertyName) == null)
{
return false;
}
return true;
}
}
}
LazyLoadableProperty类
//*******************************************************************
// 模块:延迟加载的上下文属性
// 日期:2009-9-19 14:09:46
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Contexts;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 延迟加载的上下文属性。
/// </summary>
internal class LazyLoadableProperty : IContextProperty, IContributeObjectSink
{
void IContextProperty.Freeze(Context newContext)
{
}
string IContextProperty.Name
{
get { return LazyLoadableAttribute.propertyName; }
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
LazyLoadableProperty property =
newCtx.GetProperty(LazyLoadableAttribute.propertyName) as LazyLoadableProperty;
if (property == null)
{
return false;
}
return true;
}
IMessageSink IContributeObjectSink.GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
IMessageSink sink = new LazyLoadableSink(obj, nextSink);
return sink;
}
}
}
EntityListUpdatableProperty类
//*******************************************************************
// 模块:实体集更新的上下文属性
// 日期:2009-9-19 14:24:24
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Contexts;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 实体集更新的上下文属性。
/// </summary>
internal class EntityListUpdatableProperty : IContextProperty, IContributeObjectSink
{
void IContextProperty.Freeze(Context newContext)
{
}
string IContextProperty.Name
{
get { return EntityListUpdatableAttribute.propertyName; }
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
EntityListUpdatableProperty property =
newCtx.GetProperty(EntityListUpdatableAttribute.propertyName) as EntityListUpdatableProperty;
if (property == null)
{
return false;
}
return true;
}
IMessageSink IContributeObjectSink.GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
IMessageSink sink = new EntityListUpdatableSink(obj, nextSink);
return sink;
}
}
}
在FaibClass.Data中,有两个AOP的应用,它们分别是实体集更新(DateEntityListUpdate)、延迟加载 (LazyLoad),目前的DataEntity继承于ContextBoundObject,刚刚从网上看到ContextBoundObject的损耗非常大,但自己测试了一下,应该说影响不是很大,所以暂时不打算使用静态注入了。
注,两个AOP都采用Attribute--Property--Sink的结构,每个类的具体功能请查阅相关的技术资料。
一、实体集更新(DateEntityListUpdate)
在前台设置一个实体的属性,我们在更新整个实体集到数据库的时候,并不知道哪些属性更改过,如果全部更新,将造成不必要的浪费,所以引入了这个概念。如果我们不这样做,模型类的每个属性set后将添加一句代码AddUpdateColumn。
这里使用了.Net的消息链进行处理,因为实体类上还可能使用了其他的AOP。
EntityListUpdatableAttribute类
//*******************************************************************
// 模块:指示实体对象可被集合更新
// 日期:2009-7-29 1:05
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
using FaibClass.Data.Aspect;
namespace FaibClass.Data
{
/// <summary>
/// 指示实体的属性更改后,可以使用Update更新整个实体集,如果不指定此特性,实体的DataState无法置为Modified。
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class EntityListUpdatableAttribute : Attribute, IContextAttribute, IContextProperty
{
internal static string propertyName = "EntityListUpdatable";
/// <summary>
/// 构造属性。
/// </summary>
public EntityListUpdatableAttribute()
{
}
string IContextProperty.Name
{
get { return propertyName; }
}
void IContextProperty.Freeze(Context newContext)
{
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
return true;
}
void IContextAttribute.GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
IContextProperty interceptProperty = new EntityListUpdatableProperty();
ctorMsg.ContextProperties.Add(interceptProperty);
}
bool IContextAttribute.IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
{
if (ctx.GetProperty(propertyName) == null)
{
return false;
}
return true;
}
}
}
EntityListUpdatableProperty类
//*******************************************************************
// 模块:实体集更新的上下文属性
// 日期:2009-9-19 14:24:24
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Contexts;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 实体集更新的上下文属性。
/// </summary>
internal class EntityListUpdatableProperty : IContextProperty, IContributeObjectSink
{
void IContextProperty.Freeze(Context newContext)
{
}
string IContextProperty.Name
{
get { return EntityListUpdatableAttribute.propertyName; }
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
EntityListUpdatableProperty property =
newCtx.GetProperty(EntityListUpdatableAttribute.propertyName) as EntityListUpdatableProperty;
if (property == null)
{
return false;
}
return true;
}
IMessageSink IContributeObjectSink.GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
IMessageSink sink = new EntityListUpdatableSink(obj, nextSink);
return sink;
}
}
}
EntityListUpdatableSink类
//*******************************************************************
// 模块:用于处理属性修改后的消息接收器
// 日期:2009-9-19 14:24:12
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 用于处理属性修改后的消息接收器。
/// </summary>
internal class EntityListUpdatableSink : IMessageSink
{
private IMessageSink m_nextSink;
private MarshalByRefObject m_target;
private static object syncRoot = new object();
public EntityListUpdatableSink(MarshalByRefObject target, IMessageSink nextSink)
{
lock (syncRoot)
{
m_target = target;
m_nextSink = nextSink;
}
}
public IMessage SyncProcessMessage(IMessage msg)
{
IMethodReturnMessage returnedMessage;
HandleMessage(msg, false, out returnedMessage);
return returnedMessage;
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
IMethodReturnMessage returnedMessage;
HandleMessage(msg, true, out returnedMessage);
return m_nextSink.AsyncProcessMessage(msg, replySink);
}
public IMessageSink NextSink
{
get { return m_nextSink; }
}
private void HandleMessage(IMessage msg, bool IsAsync, out IMethodReturnMessage returnedMessage)
{
returnedMessage = null;
if (!IsAsync)
{
if (msg is IMethodCallMessage)
{
IMethodCallMessage mcm = (IMethodCallMessage)msg;
bool isFill = (bool)m_target.GetType().GetProperty("InnerIsFill", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(m_target, null);
bool isProperty = !isFill && ((mcm.MethodName.Length > 4 &&
mcm.MethodName.Substring(0, 4) == "set_" && mcm.MethodName != "set_InnerIsFill" &&
mcm.MethodName != "set_InnerDataState" &&
mcm.MethodName != "set_InnerData") || mcm.MethodName == "FieldSetter");
object oldvalue = null, newvalue = null;
MemberInfo minfo = null;
string propertyName = string.Empty;
//取原来的值
if (isProperty)
{
if (mcm.MethodName == "FieldSetter")
propertyName = mcm.InArgs[1].ToString();
else
propertyName = mcm.MethodName.Replace("set_", "");
minfo = Utility.GetMember(m_target.GetType(), propertyName);
if (minfo == null)
isProperty = false;
else if (minfo.IsDefined(typeof(DataColumnAttribute), true))
oldvalue = Utility.GetMemberValue(m_target, minfo, propertyName);
}
returnedMessage = (IMethodReturnMessage)m_nextSink.SyncProcessMessage(msg);
if (isProperty)
{
//新的值
newvalue = Utility.GetMemberValue(m_target, minfo, propertyName);
if (!newvalue.Equals(oldvalue))
{
//调用内部方法添加修改了的列
m_target.GetType().InvokeMember("AddUpdateColumn", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, m_target, new object[] { mcm.MethodName.Replace("set_", "") });
}
}
}
else
{
returnedMessage = (IMethodReturnMessage)m_nextSink.SyncProcessMessage(msg);
}
}
else
{
returnedMessage = null;
}
}
}
}
二、延迟加载(LazyLoad)
没有仔细研究过其他框架的延迟加载是怎么实现的,自己还是基于.Net的消息机制做了这个功能。
LazyLoadableAttribute类
//*******************************************************************
// 模块:延迟加载的属性
// 日期:2009-9-19 14:23:22
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Contexts;
using System.Runtime.Remoting.Activation;
using FaibClass.Data.Aspect;
namespace FaibClass.Data
{
/// <summary>
/// 指示该实体中的子实体集、引用实体、引用属性可延迟载入。
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class LazyLoadableAttribute : Attribute, IContextAttribute, IContextProperty
{
internal static string propertyName = "LazyLoadable";
/// <summary>
/// 构造属性。
/// </summary>
public LazyLoadableAttribute()
{
}
string IContextProperty.Name
{
get { return propertyName; }
}
void IContextProperty.Freeze(Context newContext)
{
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
return true;
}
void IContextAttribute.GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
{
IContextProperty interceptProperty = new LazyLoadableProperty();
ctorMsg.ContextProperties.Add(interceptProperty);
}
bool IContextAttribute.IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
{
if (ctx.GetProperty(propertyName) == null)
{
return false;
}
return true;
}
}
}
LazyLoadableProperty类
//*******************************************************************
// 模块:延迟加载的上下文属性
// 日期:2009-9-19 14:09:46
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Contexts;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 延迟加载的上下文属性。
/// </summary>
internal class LazyLoadableProperty : IContextProperty, IContributeObjectSink
{
void IContextProperty.Freeze(Context newContext)
{
}
string IContextProperty.Name
{
get { return LazyLoadableAttribute.propertyName; }
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
LazyLoadableProperty property =
newCtx.GetProperty(LazyLoadableAttribute.propertyName) as LazyLoadableProperty;
if (property == null)
{
return false;
}
return true;
}
IMessageSink IContributeObjectSink.GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
IMessageSink sink = new LazyLoadableSink(obj, nextSink);
return sink;
}
}
}
EntityListUpdatableProperty类
//*******************************************************************
// 模块:实体集更新的上下文属性
// 日期:2009-9-19 14:24:24
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Contexts;
namespace FaibClass.Data.Aspect
{
/// <summary>
/// 实体集更新的上下文属性。
/// </summary>
internal class EntityListUpdatableProperty : IContextProperty, IContributeObjectSink
{
void IContextProperty.Freeze(Context newContext)
{
}
string IContextProperty.Name
{
get { return EntityListUpdatableAttribute.propertyName; }
}
bool IContextProperty.IsNewContextOK(Context newCtx)
{
EntityListUpdatableProperty property =
newCtx.GetProperty(EntityListUpdatableAttribute.propertyName) as EntityListUpdatableProperty;
if (property == null)
{
return false;
}
return true;
}
IMessageSink IContributeObjectSink.GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink)
{
IMessageSink sink = new EntityListUpdatableSink(obj, nextSink);
return sink;
}
}
}
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数