VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Objective-C编程 >
  • AOP的两个应用实体集更新DataEntityListUpdate、延迟加载Lazyload(下)

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
  LazyLoadableSink类
//*******************************************************************
// 模块:实现延迟载入的消息接收器
// 日期:2009-9-19 14:08:58
// 作者:Faib
// 版权:Copyright Faib Studio 2009
// 官网:http://www.faib.net.cn
// 邮箱:faib920@126.com
// 备注:
//*******************************************************************
using System;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using FaibClass.Data.Operation;
namespace FaibClass.Data.Aspect
{
    /// <summary>
    /// 实现延迟载入的消息接收器。
    /// </summary>
    internal class LazyLoadableSink : IMessageSink
    {
        private IMessageSink m_nextSink;
        private MarshalByRefObject m_target;
        private static object syncRoot = new object();
        public LazyLoadableSink(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; }
        }
        /// <summary>
        /// 处理消息
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="IsAsync"></param>
        /// <param name="returnedMessage"></param>
        private void HandleMessage(IMessage msg, bool IsAsync, out IMethodReturnMessage returnedMessage)
        {
            returnedMessage = null;
            if (!IsAsync)
            {
                if (msg is IMethodCallMessage)
                {
                    Type entityType = m_target.GetType();
                    IMethodCallMessage mcm = (IMethodCallMessage)msg;
                    bool isFill = (bool)entityType.GetProperty("InnerIsFill", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(m_target, null);
                    //判断是否获取属性或字段或是调用GetValue方法
                    bool isProperty = !isFill && ((mcm.MethodName.Length > 4 &&
                       mcm.MethodName.Substring(0, 4) == "get_" && mcm.MethodName != "get_InnerIsFill" &&
                       mcm.MethodName != "get_InnerDataState") || mcm.MethodName == "FieldGetter" ||
                       mcm.MethodName == "GetValue");
                    object oldvalue = null;
                    MemberInfo minfo = null;
                    //属性名字段名
                    string propertyName = string.Empty;
                    if (isProperty)
                    {
                        //字段
                        if (mcm.MethodName == "FieldGetter")
                            propertyName = mcm.InArgs[1].ToString();
                        //GetValue方法
                        else if (mcm.MethodName == "GetValue")
                            propertyName = mcm.InArgs[0].ToString();
                        //属性
                        else
                            propertyName = mcm.MethodName.Replace("get_", "");
                        minfo = Utility.GetMember(m_target.GetType(), propertyName);
                        if (minfo == null)
                            isProperty = false;
                        //判断是否子实体集、引用实体、引用属性
                        else if (!minfo.IsDefined(typeof(SubEntityListAttribute), true) &&
                            !minfo.IsDefined(typeof(ReferenceEntityAttribute), true) &&
                            !minfo.IsDefined(typeof(ReferencePropertyAttribute), true))
                            isProperty = false;
                        if (isProperty)
                            oldvalue = Utility.GetMemberValue(m_target, minfo, propertyName);
                        //值为空时才读取数据库
                        if (isProperty && oldvalue == null)
                        {
                            //取出缓存的操作对象
                            string key = DataCacheKeyManager.GetEntityInnerData(entityType);
                            object innerData = InnerCache<object[]>.Get(key);
                            if (innerData != null)
                            {
                                //构造一下操作对象
                                object[] _innerData = (object[])innerData;
                                DataHelper data = (DataHelper)Activator.CreateInstance((Type)_innerData[0]);
                                if (string.IsNullOrEmpty(data.ConnectionString))
                                    data.ConnectionString = _innerData[1].ToString();
                                OperationArgs operArgs = new OperationArgs(data);
                                QueryBuilder query = new QueryBuilder(data.CreateParameters());
                                //子实体集
                                if (minfo.IsDefined(typeof(SubEntityListAttribute), true))
                                {
                                    SubEntityListAttribute keyAttribute = DataMappingManager.GetSubEntityListKey(entityType, propertyName);
                                    if (keyAttribute != null)
                                    {
                                        IDataEntityList list = (IDataEntityList)Activator.CreateInstance(keyAttribute.EntityListType);
                                        Type refentityType = list.ModelType;
                                        //取主键值
                                        object value = ((DataEntity)m_target).GetValue(keyAttribute.PrimaryKey);
                                        if (value != null)
                                        {
                                            //关联关系
                                            query.Append(QueryCompare.Equal, keyAttribute.ForeignKey, value);
                                            if (!string.IsNullOrEmpty(keyAttribute.Condition))
                                            {
                                                query.Append(QueryRelation.And, keyAttribute.Condition);
                                            }
                                            //查询实体集
                                            list = SelectOperator.Select(operArgs, refentityType, query, null, null);
                                            returnedMessage = new ReturnMessage(list, null, 0, null, mcm);
                                            ((DataEntity)m_target).SetValue(propertyName, returnedMessage.ReturnValue);
                                        }
                                    }
                                }
                                //引用实体
                                else if (minfo.IsDefined(typeof(ReferenceEntityAttribute), true))
                                {
                                    ReferenceEntityAttribute keyAttribute = DataMappingManager.GetReferenceEntityKey(entityType, propertyName);
                                    //取主键值
                                    object value = ((DataEntity)m_target).GetValue(keyAttribute.ForeignKey);
                                    if (value != null)
                                    {
                                        //关联关系
                                        query.Append(QueryCompare.Equal, keyAttribute.PrimaryKey, value);
                                        object result = GetOperator.Get(operArgs, keyAttribute.ReferenceType, query, null, null);
                                        returnedMessage = new ReturnMessage(result, null, 0, null, mcm);
                                        ((DataEntity)m_target).SetValue(propertyName, returnedMessage.ReturnValue);
                                    }
                                }
                                //引用属性
                                else if (minfo.IsDefined(typeof(ReferencePropertyAttribute), true))
                                {
                                    ReferencePropertyAttribute keyAttribute = DataMappingManager.GetReferencePropertyKey(entityType, propertyName);
                                    //取主键值
                                    object value = ((DataEntity)m_target).GetValue(keyAttribute.ForeignKey);
                                    if (value != null)
                                    {
                                        //关联关系
                                        query.Append(QueryCompare.Equal, keyAttribute.PrimaryKey, value);
                                        DataEntity entity1 = GetOperator.Get(operArgs, keyAttribute.ReferenceType, query, null, null);
                                        if (entity1 != null)
                                        {
                                            object result = entity1.GetValue((keyAttribute as ReferencePropertyAttribute).ReferencePropertyName);
                                            returnedMessage = new ReturnMessage(result, null, 0, null, mcm);
                                            ((DataEntity)m_target).SetValue((keyAttribute as IKeyAttribute).Property, result);
                                        }
                                    }
                                }
                                data.Dispose();
                            }
                        }
                    }
                }
                if (returnedMessage == null)
                    returnedMessage = (IMethodReturnMessage)m_nextSink.SyncProcessMessage(msg);
            }
            else
            {
                returnedMessage = null;
            }
        }
    }
}
  注意,innerData是在实体集加载的时候缓存的一个操作类型及连接串,以便在这里创建操作实体来进行数据读取。
  遗憾的是,对于Field目前没有能够加载出来。
  应用这两个AOP后的模型类没有太多的改动:
    /// <summary>
    /// 公司类别模型类
    /// </summary>
    [Serializable]
    [DataTable("TCompanyType")]
    [LazyLoadable]
    [EntityListUpdatable]
    public class TCompanyType : DataEntity
    {
        
        /// <summary>
        /// 编号
        /// </summary>
        [DataColumn]
        [PrimaryKey(true)]
        public int Id;
        /// <summary>
        /// 名称
        /// </summary>
        [DataColumn]
        public string Name;
        /// <summary>
        /// 基本类别
        /// </summary>
        [DataColumn]
        public BaseType BaseType;
        /// <summary>
        /// 公司编号
        /// </summary>
        [DataColumn]
        public int CompanyId;
        /// <summary>
        /// 是否已删
        /// </summary>
        [DataColumn]
        public bool IsDelete;
        /// <summary>
        /// 上级编号
        /// </summary>
        [DataColumn]
        [ForeignKey(OperationTypes.Delete, typeof(TCompanyType), "Id")]
        public int ParentId;
        /// <summary>
        /// 子类个数
        /// </summary>
        [DataColumn]
        public int ChildCount;
        /// <summary>
        /// 排序
        /// </summary>
        [DataColumn]
        public int Sort;
        TCompanies m_Companies = null;
        /// <summary>
        /// 该类别下的所有公司
        /// </summary>
        [SubEntityList(OperationTypes.All, "ID", "CompanyTypeId")]
        public TCompanies Companies
        {
            get
            {
                return m_Companies;
            }
            set { m_Companies = value; }
        }
        TCompanyTypes m_SubCompanyTypes = null;
        /// <summary>
        /// 所有子类别
        /// </summary>
        [SubEntityList(OperationTypes.All, "ID", "ParentId")]
        public TCompanyTypes SubCompanyTypes
        {
            get
            {
                return m_SubCompanyTypes;
            }
            set { m_SubCompanyTypes = value; }
        }
    }
  前台调用代码没有改变:
        private void btnCascadeQuery_Click(object sender, EventArgs e)
        {
            //级联查询
            try
            {
                ATCompanyType da = new ATCompanyType();
                da.AccessOptions = AccessOptions.Defined;
                //排除引用实体属性
                da.PropertyFilter = null;
                //列出分类
                ListSubType(da.Select("ParentId=0"));
                da.Dispose();
            }
            catch (System.Exception e1)
            {
                ShowErrorMessage(e1.Message);
            }
        }
        //列出子分类
        private void ListSubType(TCompanyTypes list)
        {
            if (list == null) return;
            foreach(TCompanyType type in list)
            {
                //分类名称
                ShowMessage("类别名称:" + type.Name);
                //该分类下的公司
                ListSubCompany(type.Companies);
                //该分类下的子类
                ListSubType(type.SubCompanyTypes);
            }
        }
        //列出分类公司下面的子公司
        private void ListSubCompany(TCompanies companies)
        {
            if (companies == null) return;
            foreach (TCompany company in companies)
            {
                ShowMessage("公司名称:" + company.Name);
                ListSubCompany(company.SubCompanies);
            }
        }
  总结:使用继承ContextBoundObject感觉不爽,数据在经过这么多的Sink后,性能必定有所损耗,但配上分页,我想这样的不足可以有所弥补。
  声明:不要死里的盯着上面的代码,什么类不存在,我发这个的目的是阐述里面思想。
  注意,innerData是在实体集加载的时候缓存的一个操作类型及连接串,以便在这里创建操作实体来进行数据读取。
  遗憾的是,对于Field目前没有能够加载出来。
  应用这两个AOP后的模型类没有太多的改动:
    /// <summary>
    /// 公司类别模型类
    /// </summary>
    [Serializable]
    [DataTable("TCompanyType")]
    [LazyLoadable]
    [EntityListUpdatable]
    public class TCompanyType : DataEntity
    {
        
        /// <summary>
        /// 编号
        /// </summary>
        [DataColumn]
        [PrimaryKey(true)]
        public int Id;
        /// <summary>
        /// 名称
        /// </summary>
        [DataColumn]
        public string Name;
        /// <summary>
        /// 基本类别
        /// </summary>
        [DataColumn]
        public BaseType BaseType;
        /// <summary>
        /// 公司编号
        /// </summary>
        [DataColumn]
        public int CompanyId;
        /// <summary>
        /// 是否已删
        /// </summary>
        [DataColumn]
        public bool IsDelete;
        /// <summary>
        /// 上级编号
        /// </summary>
        [DataColumn]
        [ForeignKey(OperationTypes.Delete, typeof(TCompanyType), "Id")]
        public int ParentId;
        /// <summary>
        /// 子类个数
        /// </summary>
        [DataColumn]
        public int ChildCount;
        /// <summary>
        /// 排序
        /// </summary>
        [DataColumn]
        public int Sort;
        TCompanies m_Companies = null;
        /// <summary>
        /// 该类别下的所有公司
        /// </summary>
        [SubEntityList(OperationTypes.All, "ID", "CompanyTypeId")]
        public TCompanies Companies
        {
            get
            {
                return m_Companies;
            }
            set { m_Companies = value; }
        }
        TCompanyTypes m_SubCompanyTypes = null;
        /// <summary>
        /// 所有子类别
        /// </summary>
        [SubEntityList(OperationTypes.All, "ID", "ParentId")]
        public TCompanyTypes SubCompanyTypes
        {
            get
            {
                return m_SubCompanyTypes;
            }
            set { m_SubCompanyTypes = value; }
        }
    }
 


相关教程