首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

2个关于ORM只更新制定属性的设计设想解决方案

2011-12-27 
2个关于ORM只更新制定属性的设计设想2个关于ORM只更新制定属性的设计设想项目的数据访问层是参考李天平的

2个关于ORM只更新制定属性的设计设想
2个关于ORM只更新制定属性的设计设想
项目的数据访问层是参考李天平的东软代码生成工具而设计的,也是通过代码生成工具来生成数据访问层。

数据访问层到现在已经使用快2年时间,应该还算稳定。目前存在一个调优的问题。项目在后期为了加快数据访问,给数据库表建立了一些索引,虽然访问速度被加速,但在更新时的速度缺降低下来了。因为每次更新数据是数据库对索引的更新也需要花很多时间。
更新索引的原因是因为数据访问层在更新数据时除了主键ID未更新过以外,其它字段的数据都被更新了。但实际的运营情况是,每次数据更新时,对应的索引键的数据并为更新过。

针对项目存在的问题,并为了让项目能平滑升级,我设计2种更新模式:
1)给实体类的每个属性(数据库字段)增加一个内部的变量,用于记录数据库里的数值,并在每次更新数据库时做判断,如果实体类的数值被修改过,则对该数据做数据库修改的提交。
2)修改访问层的接口,增加一个本次更新列的参数,通过制定不同的更新列来。

我想在这里请教各位,使用那种模式做修改对已有项目有利,那种模式对于全新项目有利。或者各位还有什么比较好的方法对局部数据做更新。

三种数据更新的方法

C# code
    public class NewAccessCastle    {        /// <summary>        ///  旧的更新语句        /// </summary>        public void Update(Castle model)        {            SqlParameter[] parameters = GetUpdateParamter(model);            DbHelperSQL.ExecuteSql(updateSQL, parameters);        }        const string updateSQL = @"    UPDATE Castle SET     [PlayerID]=@PlayerID,[CastleID]=@CastleID,[Resource]=@Resource,[Building]=@Building    WHERE [ID]=@ID";        private static SqlParameter[] GetUpdateParamter(Castle model)        {            SqlParameter[] parameters = {                    new SqlParameter("@ID", SqlDbType.Int),                    new SqlParameter("@PlayerID", SqlDbType.Int),                    new SqlParameter("@CastleID", SqlDbType.Int),                    new SqlParameter("@Resource", SqlDbType.NVarChar),                    new SqlParameter("@Building", SqlDbType.NVarChar)};            parameters[0].Value = model.ID;            parameters[1].Value = model.PlayerID;            parameters[2].Value = model.CastleID;            parameters[3].Value = model.Resource;            parameters[4].Value = model.Building;            return parameters;        }        /// <summary>        /// 通过新旧参数判断来更新对应数据库字段        /// </summary>        /// <param name="model"></param>        public void Update1(Castle model)        {            List<SqlParameter> parameters = new List<SqlParameter>();            StringBuilder sql = new StringBuilder();            sql.Append("UPDATE Castle Set ");                     if (model.PlayerID != model.source_PlayerID)            {                sql.Append("[PlayerID]=@PlayerID,");                parameters.Add(new SqlParameter( "@PlayerID", model.PlayerID));            }            if (model.CastleID != model.source_CastleID)            {                sql.Append("[CastleID]=@CastleID,");                parameters.Add(new SqlParameter("@CastleID", model.CastleID));            }            if (model.Building != model.source_Building)            {                sql.Append("[Building]=@Building,");                parameters.Add(new SqlParameter("@Building", model.Building));            }            if (model.Resource != model.source_Resource)            {                sql.Append("[Resource]=@Resource,");                parameters.Add(new SqlParameter("@Resource", model.Resource));            }            if (parameters.Count > 0)            {                sql.Remove(sql.Length - 1, 1);                sql.Append(" where [ID]=@ID");                parameters.Add(new SqlParameter("@ID", model.ID));                DbHelperSQL.ExecuteSql(sql.ToString(), parameters.ToArray());            }        }        public enum emUpdateParameter        {            PlayerID,            CastleID,            Building,            Resource,        }        /// <summary>        /// 通过更新接口参数来确定具体的更新数据        /// </summary>        /// <param name="model"></param>        /// <param name="changeParameter"></param>        public void Update2(Castle model, params emUpdateParameter[] changeParameter)        {            if (changeParameter == null || changeParameter.Length == 0)            {                Update(model);                return;            }                            List<SqlParameter> parameters = new List<SqlParameter>();            StringBuilder sql = new StringBuilder();            sql.Append("UPDATE Castle Set ");            foreach (var change in changeParameter)            {                switch (change)                {                    case emUpdateParameter.PlayerID:                        sql.Append("[PlayerID]=@PlayerID,");                        parameters.Add(new SqlParameter("@PlayerID", model.PlayerID));                        break;                    case emUpdateParameter.CastleID:                        sql.Append("[CastleID]=@CastleID,");                        parameters.Add(new SqlParameter("@CastleID", model.CastleID));                        break;                    case emUpdateParameter.Building:                        sql.Append("[Building]=@Building,");                        parameters.Add(new SqlParameter("@Building", model.Building));                        break;                    case emUpdateParameter.Resource:                        sql.Append("[Resource]=@Resource,");                        parameters.Add(new SqlParameter("@Resource", model.Resource));                        break;                    default:                        break;                }            }            sql.Remove(sql.Length - 1, 1);            sql.Append(" where [ID]=@ID");            parameters.Add(new SqlParameter("@ID", model.ID));            DbHelperSQL.ExecuteSql(sql.ToString(), parameters.ToArray());                    }    } 



实体类可能的改动
C# code
    public class Castle    {        #region property        /// <summary>        /// 只能在dll内部访问,数据访问层单独为一个dll组件对于业务逻辑层该属性不可见        /// </summary>        internal int source_ID = 0;        int _ID = 0;        /// <summary>        ///         /// </summary>        public int ID        {            get            {                return _ID;            }            set            {                _ID = value;            }        }        internal int source_PlayerID = 0;        int _PlayerID = 0;        /// <summary>        ///         /// </summary>        public int PlayerID        {            get            {                return _PlayerID;            }            set            {                _PlayerID = value;            }        }        internal int source_CastleID = 0;        int _CastleID = 0;        /// <summary>        ///         /// </summary>        public int CastleID        {            get            {                return _CastleID;            }            set            {                _CastleID = value;            }        }        internal string source_Resource = string.Empty;        string _Resource = string.Empty;        /// <summary>        ///         /// </summary>        public string Resource        {            get            {                return _Resource;            }            set            {                _Resource = value;            }        }        internal string source_Building = string.Empty;        string _Building = string.Empty;        /// <summary>        ///         /// </summary>        public string Building        {            get            {                return _Building;            }            set            {                _Building = value;            }        }        public override string ToString()        {            StringBuilder builder = new StringBuilder();            builder.AppendFormat("ID:{0}", ID);            builder.AppendLine();            builder.AppendFormat("PlayerID:{0}", PlayerID);            builder.AppendLine();            builder.AppendFormat("CastleID:{0}", CastleID);            builder.AppendLine();            builder.AppendFormat("Resource:{0}", Resource);            builder.AppendLine();            builder.AppendFormat("Building:{0}", Building);            builder.AppendLine();            return builder.ToString();        }        #endregion        #region 拷貝構造函數        public Castle()        {        }        public Castle(Castle _Castle)        {            ID = _Castle.ID;            PlayerID = _Castle.PlayerID;            CastleID = _Castle.CastleID;            Resource = _Castle.Resource;            Building = _Castle.Building;        }        #endregion        /// <summary>        /// 实体类数据是否发生过修改        /// </summary>        /// <returns></returns>        public bool hasChange()        {            if (PlayerID != source_PlayerID)                return false;            if (CastleID != source_CastleID)                return false;            if (Building != source_Building)                return false;            if (Resource != source_Resource)                return false;            return true;        }    }


[解决办法]
问题在于这里:"更新索引的原因是因为数据访问层在更新数据时除了主键ID未更新过以外,其它字段的数据都被更新了。但实际的运营情况是,每次数据更新时,对应的索引键的数据并为更新过。"

请确定你创建的索引合理,索引不合理(索引过多,非聚集索引弄成了聚集索引或者反之,长期不整理优化索引,)使用的语句不合理,其影响的效能比你程式代码产生的影响大太多了.
[解决办法]
List<T>保存修改字段或相关值


也可使用Dictionary

[解决办法]
楼主思路存在重大问题:
1、就更新而言:没有考虑并发,你的意思是在Update之前判断字段的新旧值,可是你拿来比较的旧值很可能已经在你判断的时候被其他客户端update了,如果非要这样做的话就在存储过程中处理吧,修改一下原有的update语句直接搞定,不需要额外增加其他语句;
在设计这类问题时首先避免多步操作,其次依赖系统事务减少并发问题产生的几率;
2、分层不是你们这样分的:bll和Dal的代码量应该是固定的,不会随着功能窗口的增加而增加,也不会随着table或sp的增加而增加,我们的项目的sp达到1000个是很平常的事情,照你们这样就是一个个生成也是很恐怖的事情啊;
3、项目代码既可以手写也可以自动生成,不过一般是生成的,只在研发新的模型或用例时才手写,不应该出现不方便手工修改的情况,东软的代码生成工具我评估过,跟petshop差不多,搞搞课堂学习还可以,用作生产工具的话,离工业化要求还相差甚远。

[解决办法]
楼主好辛苦啊,顶一下!!

热点排行