中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

DDD~基礎(chu)設施層

回到目錄

最近被DDD吸(xi)引了阿,在這(zhe)里(li)感謝一(yi)(yi)下小佟(tong),呵呵,領域驅動(dong)設計是個不錯的(de)(de)東西,幫(bang)助我們把問題(ti)清晰(xi)化(hua),這(zhe)候對(dui)于(yu)復雜業(ye)務邏(luo)輯是很重(zhong)要的(de)(de),今天這(zhe)一(yi)(yi)講(jiang)主要說(shuo)一(yi)(yi)下DDD中(zhong)的(de)(de)基礎設施層(Infrastructure)是如何(he)被我實現(xian)的(de)(de)。

Infrastructure Layer:主要功(gong)能(neng)(neng)是對(dui)(dui)領域模塊進行持久化的(de),在這個層中(zhong)你需(xu)要把領域對(dui)(dui)象序列化到指定的(de)元件(jian)(jian)中(zhong),可能(neng)(neng)是數(shu)據庫,文件(jian)(jian)或者內存對(dui)(dui)象,當然它也要提(ti)供從物理元件(jian)(jian)取出數(shu)據到領域模型的(de)功(gong)能(neng)(neng),這是對(dui)(dui)應的(de)。

目前的DDD項目結果如下

對于Infrastructure這個層我不(bu)去定義接口而(er)是讓(rang)它去實現Domain層的接口,即(ji)一(yi)切(qie)從領域出發,而(er)Infrastructure只負責具(ju)體的數據持久化工作(zuo),下面(mian)我們主要介紹(shao)一(yi)下IRepository.cs和IExtensionRepository.cs在(zai)Infrastructure層是如何被實現的。

與傳統DATA層的區別

一 傳統Data層定義接口,為(wei)數(shu)據為(wei)導向,而不是以業務(wu)為(wei)導。

二 將Repository的方(fang)法中添(tian)加了領域規約(yue),使它Infrastructure更有目的的去實現。

引入工作單元,使多方法形式一個事務的概念

IUnitOfWork接(jie)口也(ye)是在domain層實(shi)現的,不過在這里(li)我們也(ye)介紹一(yi)下它(ta)的代碼

    public interface IUnitOfWork
    {
        /// <summary>
        /// 將操(cao)作提交到(dao)數(shu)據庫,
        /// </summary>
        void Save();
        /// <summary>
        /// 是否(fou)需要顯示進行提交(jiao)(save())
        /// 默認為(wei)false,即在repository方法中自動完成提交,值(zhi)為(wei)true時,表(biao)示(shi)需要(yao)顯(xian)示(shi)調用save()方法
        /// </summary>
        /// <returns></returns>
        bool IsExplicitSubmit { get; set; }
    }

工作單元會有(you)保存save操作和是否顯(xian)示提(ti)交(jiao)的(de)(de)屬性,開發人員可(ke)以(yi)根(gen)據業務情況去(qu)選擇IsExplicitSubmit的(de)(de)狀態(tai),默認(ren)是自動提(ti)交(jiao),如果(guo)希望多個方法統一一次提(ti)

交,可以將IsExplicitSubmit設為true,然(ran)后手動進行save(),這(zhe)是有(you)助于提(ti)升程(cheng)序(xu)性能的。

Infrastructure層的核心代碼

    public class DbContextRepository<TEntity> :
        IExtensionRepository<TEntity>
        where TEntity : class
    {
        #region Constructors
        public DbContextRepository(IUnitOfWork db, Action<string> logger)
        {
            iUnitWork = db;
            _Db = (DbContext)db;
            Logger = logger;
            ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;
        }

        public DbContextRepository(IUnitOfWork db)
            : this(db, null)
        { }

        #endregion

        #region Properties
        /// <summary>
        /// 數(shu)據上下文(wen)
        /// </summary>
        protected DbContext _Db { get; private set; }
        /// <summary>
        /// 工作(zuo)單元上下文,子類(lei)可以(yi)直接使(shi)用它
        /// </summary>
        protected IUnitOfWork iUnitWork { get; set; }

        /// <summary>
        /// Action委托事(shi)例(li),在派生類可以操(cao)作它
        /// </summary>
        protected Action<string> Logger { get; private set; }

        /// <summary>
        /// 得到上(shang)下文(wen)中表對象的(de)所有記錄數
        /// 當(dang)數據表記錄在千(qian)萬以(yi)上(shang)時(shi),select count(1) from table
        /// 的(de)速(su)度會受到影(ying)響(xiang),所以擴(kuo)展一(yi)個方法解決這個問題
        /// </summary>
        /// <param name="queryable"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public int RecordCount
        {
            get
            {
                return Convert.ToInt32(_Db.Database.SqlQuery<long>(
                    "SELECT ROWCNT FROM SYSINDEXES WHERE ID=OBJECT_ID('" + typeof(TEntity).Name + "') AND INDID<2").First());
            }
        }
        #endregion

        #region Fields
        /// <summary>
        /// 數(shu)據總數(shu)
        /// </summary>
        int DataTotalCount = 0;

        /// <summary>
        /// 數據(ju)總頁數
        /// </summary>
        int DataTotalPages = 0;

        /// <summary>
        /// 數(shu)據(ju)(ju)頁面(mian)大小(每次向數(shu)據(ju)(ju)庫提交的記錄(lu)數(shu))
        /// </summary>
        int DataPageSize = 10000;
        #endregion

        #region IRepository<T> 成員

        public virtual void Insert(TEntity item)
        {
            OnBeforeSaved(new SavedEventArgs(item, SaveAction.Insert));
            _Db.Entry<TEntity>(item);
            _Db.Set<TEntity>().Add(item);
            this.SaveChanges();
            OnAfterSaved(new SavedEventArgs(item, SaveAction.Insert));
        }

        public virtual void Delete(TEntity item)
        {
            OnBeforeSaved(new SavedEventArgs(item, SaveAction.Delete));
            _Db.Set<TEntity>().Attach(item);
            _Db.Set<TEntity>().Remove(item);
            this.SaveChanges();
            OnAfterSaved(new SavedEventArgs(item, SaveAction.Delete));
        }

        public virtual void Update(TEntity item)
        {
            OnBeforeSaved(new SavedEventArgs(item, SaveAction.Update));
            _Db.Set<TEntity>().Attach(item);
            _Db.Entry(item).State = EntityState.Modified;
            this.SaveChanges();
            OnAfterSaved(new SavedEventArgs(item, SaveAction.Update));
        }

        public IQueryable<TEntity> GetModel()
        {
            return _Db.Set<TEntity>().AsNoTracking();//對象(xiang)無(wu)法自動添加(jia)到上下文中(zhong),因(yin)為它是使用 NoTracking 合并(bing)選項檢索(suo)的(de)。請在定義此關系之前(qian),將該實體(ti)顯式(shi)附加(jia)到 ObjectContext。
            // return _Db.Set<TEntity>();
        }

        #endregion

        #region IExtensionRepository<T> 成員

        public virtual void Insert(IEnumerable<TEntity> item)
        {
            item.ToList().ForEach(i =>
            {
                _Db.Entry<TEntity>(i);
                _Db.Set<TEntity>().Add(i);
            });
            this.SaveChanges();
        }

        public virtual void Delete(IEnumerable<TEntity> item)
        {
            item.ToList().ForEach(i =>
            {
                _Db.Set<TEntity>().Attach(i);
                _Db.Set<TEntity>().Remove(i);
            });
            this.SaveChanges();
        }

        public virtual void Update(IEnumerable<TEntity> item)
        {
            item.ToList().ForEach(i =>
            {
                _Db.Set<TEntity>().Attach(i);
                _Db.Entry(i).State = EntityState.Modified;
            });
            this.SaveChanges();
        }

        public void Update<T>(Expression<Action<T>> entity) where T : class
        {

            T newEntity = typeof(T).GetConstructor(Type.EmptyTypes).Invoke(null) as T;//建立指(zhi)定類型的實(shi)例
            List<string> propertyNameList = new List<string>();
            MemberInitExpression param = entity.Body as MemberInitExpression;
            foreach (var item in param.Bindings)
            {
                string propertyName = item.Member.Name;
                object propertyValue;
                var memberAssignment = item as MemberAssignment;
                if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
                {
                    propertyValue = (memberAssignment.Expression as ConstantExpression).Value;
                }
                else
                {
                    propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
                }
                typeof(T).GetProperty(propertyName).SetValue(newEntity, propertyValue, null);
                propertyNameList.Add(propertyName);
            }
            _Db.Set<T>().Attach(newEntity);
            _Db.Configuration.ValidateOnSaveEnabled = false;
            var ObjectStateEntry = ((IObjectContextAdapter)_Db).ObjectContext.ObjectStateManager.GetObjectStateEntry(newEntity);
            propertyNameList.ForEach(x => ObjectStateEntry.SetModifiedProperty(x.Trim()));
            this.SaveChanges();
            // ((IObjectContextAdapter)_Db).ObjectContext.Detach(newEntity);
        }

        public TEntity Find(params object[] id)
        {
            return _Db.Set<TEntity>().Find(id);
        }

        public IQueryable<TEntity> GetModel(ISpecification<TEntity> specification)
        {
            return GetModel().Where(specification.SatisfiedBy());
        }

        public IQueryable<TEntity> GetModel(Expression<Func<TEntity, bool>> predicate)
        {
            return GetModel().Where(predicate);
        }

        public IQueryable<TEntity> GetModel<S>(Expression<Func<TEntity, S>> orderByExpression, bool asc)
        {
            Orderable<TEntity> order = new Orderable<TEntity>(this.GetModel());
            if (asc)
                order.Asc(orderByExpression);
            else
                order.Desc(orderByExpression);
            return order.Queryable;
        }

        public TEntity Find(Expression<Func<TEntity, bool>> predicate)
        {
            return GetModel(predicate).FirstOrDefault();
        }

        public TEntity Find(ISpecification<TEntity> specification)
        {
            return GetModel(specification).FirstOrDefault();
        }

        public void BulkInsert(IEnumerable<TEntity> item)
        {
            DataPageProcess(item, (currentItems) =>
            {
                ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不超時
                _Db.Database.ExecuteSqlCommand(DoSQL(currentItems, SQLType.Insert));
            });
        }

        public void BulkDelete(IEnumerable<TEntity> item)
        {
            DataPageProcess(item, (currentItems) =>
            {
                ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不超時
                _Db.Database.ExecuteSqlCommand(DoSQL(currentItems, SQLType.Delete));
            });
        }

        public void BulkUpdate(IEnumerable<TEntity> item, params string[] fieldParams)
        {
            DataPageProcess(item, (currentItems) =>
            {
                ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不(bu)超時
                _Db.Database.ExecuteSqlCommand(DoSQL(currentItems, SQLType.Update, fieldParams));
            });
        }

        public void BulkUpdate(IEnumerable<Expression<Action<TEntity>>> expressionList)
        {
            DataPageProcess(expressionList, (currentItems) =>
            {
                StringBuilder sqlstr = new StringBuilder();
                currentItems.ToList().ForEach(i =>
                {
                    Tuple<string, object[]> sql = CreateUpdateSQL(i);
                    sqlstr.AppendFormat(sql.Item1, sql.Item2);
                });
                ((IObjectContextAdapter)_Db).ObjectContext.CommandTimeout = 0;//永不超時
                _Db.Database.ExecuteSqlCommand(sqlstr.ToString());
            });
        }

        public event Action<SavedEventArgs> AfterSaved;

        public event Action<SavedEventArgs> BeforeSaved;

        #endregion

        #region Protected Methods
        /// <summary>
        /// 根(gen)據工作單元的IsUnitOfWork的屬性,去判斷是否提交到數(shu)據庫
        /// 一般地,在多個(ge)repository類型進(jin)行組(zu)合時(shi),這個(ge)IsUnitOfWork都會設為(wei)true,即不馬上提交,
        /// 而對于單個repository操作來說,它的(de)(de)值不需要(yao)設置,使(shi)用默(mo)認的(de)(de)false,將(jiang)直接提交到數據(ju)庫,這也保證了操作的(de)(de)原子性。
        /// </summary>
        protected void SaveChanges()
        {
            try
            {
                if (!iUnitWork.IsExplicitSubmit)// if (iUnitWork.IsUnitOfWork ^ true)
                    iUnitWork.Save();
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
            {
                if (Logger == null)
                    throw dbEx;
                Logger(dbEx.Message);
            }
            catch (Exception ex)
            {
                if (Logger == null)//如果沒(mei)有(you)定義日志功能,就把異(yi)常拋(pao)出來吧
                    throw ex;
                Logger(ex.Message);
            }

        }

        /// <summary>
        ///  計數更新,與SaveChange()是兩個SQL鏈接(jie),走分(fen)布式事(shi)務
        ///  子類可(ke)以根據自(zi)己的邏(luo)輯,去復寫
        ///  tableName:表名
        ///  param:索引0為(wei)主(zhu)鍵名,1表主(zhu)鍵值,2為(wei)要計數的(de)字段,3為(wei)增量
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="param">參數(shu)列表(biao)(biao),索引0為主(zhu)鍵(jian)名,1表(biao)(biao)主(zhu)鍵(jian)值,2為要計數(shu)的字段(duan),3為增(zeng)量</param>
        protected virtual void UpdateForCount(string tableName, params object[] param)
        {
            string sql = "UPDATE [" + tableName + "] SET [{2}]=ISNULL([{2}],0)+{3} WHERE [{0}]={1}";
            List<object> listParasm = new List<object>
            {
                param[0],
                param[1],
                param[2],
                param[3],
            };
            _Db.Database.ExecuteSqlCommand(string.Format(sql, listParasm.ToArray()));
        }
        #endregion

        #region Virtual Methods

        /// <summary>
        /// Called after data saved
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="action">The action.</param>
        protected virtual void OnAfterSaved(SavedEventArgs e)
        {
            if (AfterSaved != null)
            {
                AfterSaved(e);
            }
        }

        /// <summary>
        /// Called before saved
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="action">The action.</param>
        protected virtual void OnBeforeSaved(SavedEventArgs e)
        {
            if (BeforeSaved != null)
            {
                BeforeSaved(e);
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 分(fen)頁進行數據提交的邏輯
        /// </summary>
        /// <param name="item">原列表(biao)</param>
        /// <param name="method">處理方法</param>
        /// <param name="currentItem">要進行(xing)處理的(de)新列表(biao)</param>
        private void DataPageProcess(
            IEnumerable<TEntity> item,
            Action<IEnumerable<TEntity>> method)
        {
            if (item != null && item.Count() > 0)
            {
                DataTotalCount = item.Count();
                this.DataTotalPages = item.Count() / DataPageSize;
                if (DataTotalCount % DataPageSize > 0)
                    DataTotalPages += 1;
                for (int pageIndex = 1; pageIndex <= DataTotalPages; pageIndex++)
                {
                    var currentItems = item.Skip((pageIndex - 1) * DataPageSize).Take(DataPageSize).ToList();
                    method(currentItems);
                }
            }
        }

        private void DataPageProcess(
            IEnumerable<Expression<Action<TEntity>>> item,
            Action<IEnumerable<Expression<Action<TEntity>>>> method)
        {
            if (item != null && item.Count() > 0)
            {
                DataTotalCount = item.Count();
                this.DataTotalPages = item.Count() / DataPageSize;
                if (DataTotalCount % DataPageSize > 0)
                    DataTotalPages += 1;
                for (int pageIndex = 1; pageIndex <= DataTotalPages; pageIndex++)
                {
                    var currentItems = item.Skip((pageIndex - 1) * DataPageSize).Take(DataPageSize).ToList();
                    method(currentItems);
                }
            }
        }

        private static string GetEqualStatment(string fieldName, int paramId, Type pkType)
        {
            if (pkType.IsValueType)
                return string.Format("{0} = {1}", fieldName, GetParamTag(paramId));
            return string.Format("{0} = '{1}'", fieldName, GetParamTag(paramId));

        }

        private static string GetParamTag(int paramId)
        {
            return "{" + paramId + "}";
        }

        /// <summary>
        /// 得(de)到實體鍵EntityKey
        /// </summary>
        /// <typeparam name="TEntity"></typeparam&gt;
        /// <returns></returns>
        protected ReadOnlyMetadataCollection<EdmMember> GetPrimaryKey()
        {
            EntitySetBase primaryKey = ((IObjectContextAdapter)_Db).ObjectContext.GetEntitySet(typeof(TEntity));
            ReadOnlyMetadataCollection<EdmMember> arr = primaryKey.ElementType.KeyMembers;
            return arr;
        }

        /// <summary>
        /// 構建Update語句串
        /// 注意:如(ru)果本方法過濾了(le)int,decimal類型(xing)更(geng)新為0的列,如(ru)果希(xi)望更(geng)新它們需要指(zhi)定FieldParams參數(shu)
        /// </summary>
        /// <param name="entity">實體列表</param>
        /// <param name="fieldParams">要更(geng)新的字段(duan)</param>
        /// <returns></returns>
        private Tuple<string, object[]> CreateUpdateSQL(Expression<Action<TEntity>> expression)
        {

            TEntity entity = typeof(TEntity).GetConstructor(Type.EmptyTypes).Invoke(null) as TEntity;//建立指定(ding)類型的實例
            List<string> propertyNameList = new List<string>();
            MemberInitExpression param = expression.Body as MemberInitExpression;
            foreach (var item in param.Bindings)
            {
                string propertyName = item.Member.Name;
                object propertyValue;
                var memberAssignment = item as MemberAssignment;
                if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
                {
                    propertyValue = (memberAssignment.Expression as ConstantExpression).Value;
                }
                else
                {
                    propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
                }
                typeof(TEntity).GetProperty(propertyName).SetValue(entity, propertyValue, null);
                propertyNameList.Add(propertyName);
            }
            return CreateUpdateSQL(entity, propertyNameList.ToArray());
        }

        /// <summary>
        /// 構建Update語句串(chuan)
        /// 注意:如果本(ben)方法過濾了int,decimal類型更(geng)新為0的(de)列,如果希望更(geng)新它們需要指(zhi)定FieldParams參(can)數(shu)
        /// </summary>
        /// <param name="entity">實體列(lie)表(biao)</param>
        /// <param name="fieldParams">要(yao)更新的字段</param>
        /// <returns></returns>
        private Tuple<string, object[]> CreateUpdateSQL(TEntity entity, params string[] fieldParams)
        {
            if (entity == null)
                throw new ArgumentException("The database entity can not be null.");
            List<string> pkList = GetPrimaryKey().Select(i => i.Name).ToList();

            Type entityType = entity.GetType();
            List<PropertyInfo> tableFields = new List<PropertyInfo>();
            if (fieldParams != null && fieldParams.Count() > 0)
            {
                tableFields = entityType.GetProperties().Where(i => fieldParams.Contains(i.Name, new StringComparisonIgnoreCase())).ToList();
            }
            else
            {
                tableFields = entityType.GetProperties().Where(i =>
                              !pkList.Contains(i.Name)
                              && i.GetValue(entity, null) != null
                              && !(i.PropertyType == typeof(ValueType) && Convert.ToInt64(i.GetValue(entity, null)) == 0)
                              && !(i.PropertyType == typeof(DateTime) && Convert.ToDateTime(i.GetValue(entity, null)) == DateTime.MinValue)
                              && i.PropertyType != typeof(EntityState)
                              && !(i.GetCustomAttributes(false).Length > 0
                              && i.GetCustomAttributes(false).Where(j => j.GetType() == typeof(NavigationAttribute)) != null)//過濾導航屬性(xing)
                              && (i.PropertyType.IsValueType || i.PropertyType == typeof(string))
                               ).ToList();
            }




            //過濾(lv)主鍵,航行屬(shu)性(xing),狀態屬(shu)性(xing)等(deng)
            if (pkList == null || pkList.Count == 0)
                throw new ArgumentException("The Table entity have not a primary key.");
            List<object> arguments = new List<object>();
            StringBuilder builder = new StringBuilder();

            foreach (var change in tableFields)
            {
                if (pkList.Contains(change.Name))
                    continue;
                if (arguments.Count != 0)
                    builder.Append(", ");
                builder.Append(change.Name + " = {" + arguments.Count + "}");
                if (change.PropertyType == typeof(string)
                    || change.PropertyType == typeof(DateTime)
                    || change.PropertyType == typeof(Nullable<DateTime>))
                    arguments.Add("'" + change.GetValue(entity, null).ToString().Replace("'", "char(39)") + "'");
                else
                    arguments.Add(change.GetValue(entity, null));
            }

            if (builder.Length == 0)
                throw new Exception("沒有任何屬性進行更新(xin)");

            builder.Insert(0, " UPDATE " + string.Format("[{0}]", entityType.Name) + " SET ");

            builder.Append(" WHERE ");
            bool firstPrimaryKey = true;

            foreach (var primaryField in pkList)
            {
                if (firstPrimaryKey)
                    firstPrimaryKey = false;
                else
                    builder.Append(" AND ");

                object val = entityType.GetProperty(primaryField).GetValue(entity, null);
                Type pkType = entityType.GetProperty(primaryField).GetType();
                builder.Append(GetEqualStatment(primaryField, arguments.Count, pkType));
                arguments.Add(val);
            }
            return new Tuple<string, object[]>(builder.ToString(), arguments.ToArray());

        }

        /// <summary>
        /// 構建Delete語句串
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        private Tuple<string, object[]> CreateDeleteSQL(TEntity entity)
        {
            if (entity == null)
                throw new ArgumentException("The database entity can not be null.");

            Type entityType = entity.GetType();
            List<string> pkList = GetPrimaryKey().Select(i => i.Name).ToList();
            if (pkList == null || pkList.Count == 0)
                throw new ArgumentException("The Table entity have not a primary key.");

            List<object> arguments = new List<object>();
            StringBuilder builder = new StringBuilder();
            builder.Append(" Delete from " + string.Format("[{0}]", entityType.Name));

            builder.Append(" WHERE ");
            bool firstPrimaryKey = true;

            foreach (var primaryField in pkList)
            {
                if (firstPrimaryKey)
                    firstPrimaryKey = false;
                else
                    builder.Append(" AND ");

                Type pkType = entityType.GetProperty(primaryField).GetType();
                object val = entityType.GetProperty(primaryField).GetValue(entity, null);
                builder.Append(GetEqualStatment(primaryField, arguments.Count, pkType));
                arguments.Add(val);
            }
            return new Tuple<string, object[]>(builder.ToString(), arguments.ToArray());
        }

        /// <summary>
        /// 構建Insert語句串
        /// 主(zhu)鍵為(wei)自增時,如果主(zhu)鍵值為(wei)0,我們將主(zhu)鍵插入(ru)到SQL串中
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        private Tuple<string, object[]> CreateInsertSQL(TEntity entity)
        {
            if (entity == null)
                throw new ArgumentException("The database entity can not be null.");

            Type entityType = entity.GetType();
            var table = entityType.GetProperties().Where(i => i.PropertyType != typeof(EntityKey)
                 && i.PropertyType != typeof(EntityState)
                 && i.Name != "IsValid"
                 && i.GetValue(entity, null) != null
                 && !(i.GetCustomAttributes(false).Length > 0
                 && i.GetCustomAttributes(false).Where(j => j.GetType() == typeof(NavigationAttribute)) != null)
                 && (i.PropertyType.IsValueType || i.PropertyType == typeof(string))).ToArray();//過(guo)濾主(zhu)鍵,航行屬(shu)性(xing),狀(zhuang)態屬(shu)性(xing)等

            List<string> pkList = GetPrimaryKey().Select(i => i.Name).ToList();
            List<object> arguments = new List<object>();
            StringBuilder fieldbuilder = new StringBuilder();
            StringBuilder valuebuilder = new StringBuilder();

            fieldbuilder.Append(" INSERT INTO " + string.Format("[{0}]", entityType.Name) + " (");

            foreach (var member in table)
            {
                if (pkList.Contains(member.Name) && Convert.ToString(member.GetValue(entity, null)) == "0")
                    continue;
                object value = member.GetValue(entity, null);
                if (value != null)
                {
                    if (arguments.Count != 0)
                    {
                        fieldbuilder.Append(", ");
                        valuebuilder.Append(", ");
                    }

                    fieldbuilder.Append(member.Name);
                    if (member.PropertyType == typeof(string)
                        || member.PropertyType == typeof(DateTime)
                        || member.PropertyType == typeof(Nullable<DateTime>)
                        )
                        valuebuilder.Append("'{" + arguments.Count + "}'");
                    else
                        valuebuilder.Append("{" + arguments.Count + "}");
                    if (value.GetType() == typeof(string))
                        value = value.ToString().Replace("'", "char(39)");
                    arguments.Add(value);

                }
            }


            fieldbuilder.Append(") Values (");

            fieldbuilder.Append(valuebuilder.ToString());
            fieldbuilder.Append(");");
            return new Tuple<string, object[]>(fieldbuilder.ToString(), arguments.ToArray());
        }

        /// <summary>
        /// /// <summary>
        /// 執行SQL,根據SQL操作的類(lei)型
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="list"></param>
        /// <param name="sqlType"></param>
        /// <returns></returns>
        /// </summary>
        /// <param name="list"></param>
        /// <param name="sqlType"></param>
        /// <returns></returns>
        private string DoSQL(IEnumerable<TEntity> list, SQLType sqlType)
        {
            return DoSQL(list, sqlType, null);
        }
        /// <summary>
        /// 執行SQL,根(gen)據SQL操(cao)作的(de)類型
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="list"></param>
        /// <param name="sqlType"></param>
        /// <returns></returns>
        private string DoSQL(IEnumerable<TEntity> list, SQLType sqlType, params string[] fieldParams)
        {
            StringBuilder sqlstr = new StringBuilder();
            switch (sqlType)
            {
                case SQLType.Insert:
                    list.ToList().ForEach(i =>
                    {
                        Tuple<string, object[]> sql = CreateInsertSQL(i);
                        sqlstr.AppendFormat(sql.Item1, sql.Item2);
                    });
                    break;
                case SQLType.Update:
                    list.ToList().ForEach(i =>
                    {
                        Tuple<string, object[]> sql = CreateUpdateSQL(i, fieldParams);
                        sqlstr.AppendFormat(sql.Item1, sql.Item2);
                    });
                    break;
                case SQLType.Delete:
                    list.ToList().ForEach(i =>
                    {
                        Tuple<string, object[]> sql = CreateDeleteSQL(i);
                        sqlstr.AppendFormat(sql.Item1, sql.Item2);
                    });
                    break;
                default:
                    throw new ArgumentException("請輸入正確的(de)參(can)數");
            }
            return sqlstr.ToString();
        }

        /// <summary>
        /// SQL操作類型(xing)
        /// </summary>
        protected enum SQLType
        {
            /// <summary>
            /// 更新(xin)傳入的實體代碼去添加
            /// </summary>
            Insert,
            /// <summary>
            /// 根據傳入(ru)的實體列表去更新
            /// </summary>
            Update,
            /// <summary>
            /// 根據傳(chuan)入的實體列(lie)表去刪除
            /// </summary>
            Delete,
        }
        #endregion
    }

下面看一下對于基礎設施層所依賴的程序集

可以看到,它(ta)主(zhu)要依(yi)賴于領域(yu)實(shi)體(ti)層與領域(yu)實(shi)體(ti)規約層。

OK,對于基(ji)礎設施層的(de)搭建(jian)就(jiu)說(shuo)到這,下(xia)回(hui)我(wo)們將說(shuo)一下(xia)領域層的(de)搭建(jian)。

回到目錄

posted @ 2013-02-21 13:58  張占嶺  閱讀(11347)  評論(7)    收藏  舉報