一 : 保护基础设施和水系规划首设“黄线”“蓝线”
我市规划首设“黄线”“蓝线”分别用于保护城市基础设施和城市水系
继“红线”、“绿线”、“紫线”之后,分别用于保障城市基础设施用地和保护城市水系的“黄线”和“蓝线”也将在我市出现。昨日,市规划局正式公布了《厦门市城市黄线控制规划》和《厦门市蓝线控制规划》。“黄线”主要对城市基础设施用地界线进行控制,而“蓝线”主要是加强厦门水系的保护与管理,保障供水、防洪防涝和通航安全。
黄线
机场红线范围内严禁项目建设;电信运营商在厦门岛外各设置一座枢纽局;结合城市建设,有计划地建立防灾据点
此次出台的《厦门市城市黄线控制规划》主要对交通、给水、排水、环卫、燃气、电力、通讯、防洪排涝、防灾等设施进行规划控制。
其中,在交通方面,规划指出,高崎国际机场红线范围内不允许其他用途的项目开发建设,远期可考虑新建第二国际机场。在通讯方面,规划各电信运营商在厦门岛外各设置一座枢纽局,枢纽局用地控制在10000平方米-15000平方米。规划在厦门市岛外东部翔安城市副中心新增一座广播电视中心,占地25000平方米。同时,为满足岛外集美区和海沧区的用地需求,规划指出,201电台和202电台需要尽快重新选址。
在防灾设施方面,规划强调,结合旧城改造,拆除危旧房,增加城市绿地和住宅区绿地;平时加强管理,震时供作避震疏散使用。结合城市建设,有计划地建立防灾据点(如学校、医院等);提高防灾据点内市政设施和骨干建筑的抗震设防标准,以作为避震疏散和抢险救灾的根据地。结合危旧房屋改造和房改政策的实施,适当开发地下空间,做到平震结合。
规划还指出,根据《厦门市气象设施规划》,保留狐尾山顶气象观测站,调整为国家气象观测站一级站。调整同安大同镇梅山西侧山脚、环城东路东侧观测站为二级站,并增加大嶝、海沧二级观测站两处。
蓝线
需要保护控制的城市水域包括全市小(ⅰ)以上水库、对全市有重要影响的渠道(如北溪引水渠道)、9条主要溪流和3种类型的滨海湿地
此次《厦门市蓝线控制规划》的研究范围主要为,需要保护控制的城市水域包括水库、渠、溪流和湿地。
其中,水库蓝线规划的主要对象为全市小(ⅰ)以上水库。水库的蓝线控制范围包括库区、汇水区及饮用水输水管渠,根据不同的控制要求,包括以下3条控制线:最高蓄水水位线、一级保护区控制线、二级保护区控制线。水坝、泄水渠道等水库水工构筑物管理要求参照《厦门市水工程管理规定》执行。
渠道蓝线规划确定对全市有重要影响的渠道为北溪引水渠道、特区供水管道、石兜水库至集美大池管道、汀溪水库总干渠和第一支渠及大嶝供水管道。
作为水体控制线,溪流蓝线规划的对象为9条主要溪流,包括过芸溪、深青溪、瑶山溪、后溪、东西溪、官浔溪、埭头溪、三忠溪和九溪。
湿地蓝线规划从宏观层次上将厦门市滨海湿地划分为红树林管护区、海洋生物保护区和一般控制区3种类型的生态功能区。红树林管护区主要集中在五缘湾生态修复区、翔安鳄鱼屿、同安下潭尾湿地生态修复区、官浔溪湿地公园、集美北部滨海湿地公园、杏滨高浦生态修复区、马銮西滨湿地保护区、海沧火烧屿-大小兔屿-大屿湿地生态修复区等区域。海洋生物保护区主要有:翔安刘五店中华白海豚保护区、大嶝文昌鱼保护区、马銮湾口中华白海豚保护区、海沧大屿-鸡屿白鹭保护区、本岛黄厝文昌鱼保护区。
名词解释
城市黄线是指对城市发展全局有影响的、城市规划中确定的、必须控制的城市基础设施用地的控制界线。
城市蓝线是指城市规划确定的江、河、湖、库、渠和湿地等城市地表水保护和控制的地域界线。
二 : DDD~基础设施层
回到目录
最近被DDD吸引了阿,在这里感谢一下小佟,呵呵,领域驱动设计是个不错的东西,帮助我们把问题清晰化,这候对于复杂业务逻辑是很重要的,今天这一讲主要说一下DDD中的基础设施层(Infrastructure)是如何被我实现的。(www.61k.com]
Infrastructure Layer:主要功能是对领域模块进行持久化的,在这个层中你需要把领域对象序列化到指定的元件中,可能是数据库,文件或者内存对象,当然它也要提供从物理元件取出数据到领域模型的功能,这是对应的。
目前的DDD项目结果如下
扩展:基础设施层 / 系统架构 基础设施层 / ddd 防腐层
对于Infrastructure这个层我不去定义接口而是让它去实现Domain层的接口,即一切从领域出发,而Infrastructure只负责具体的数据持久化工作,下面我们主要介绍一下IRepository.cs和IExtensionRepository.cs在Infrastructure层是如何被实现的。
与传统DATA层的区别
一 传统Data层定义接口,为数据为导向,而不是以业务为导。
二 将Repository的方法中添加了领域规约,使它Infrastructure更有目的的去实现。
引入工作单元,使多方法形式一个事务的概念
IUnitOfWork接口也是在domain层实现的,不过在这里我们也介绍一下它的代码
public interface IUnitOfWork { /// <summary> /// 将操作提交到数据库, /// </summary> void Save(); /// <summary> /// 是否需要显示进行提交(save()) /// 默认为false,即在repository方法中自动完成提交,值为true时,表示需要显示调用save()方法 /// </summary> /// <returns></returns> bool IsExplicitSubmit { get; set; } }
工作单元会有保存save操作和是否显示提交的属性,开发人员可以根据业务情况去选择IsExplicitSubmit的状态,默认是自动提交,如果希望多个方法统一一次提
交,可以将IsExplicitSubmit设为true,然后手动进行save(),这是有助于提升程序性能的。
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> /// 数据上下文 /// </summary> protected DbContext _Db { get; private set; } /// <summary> /// 工作单元上下文,子类可以直接使用它 /// </summary> protected IUnitOfWork iUnitWork { get; set; } /// <summary> /// Action委托事例,在派生类可以操作它 /// </summary> protected Action<string> Logger { get; private set; } /// <summary> /// 得到上下文中表对象的所有记录数 /// 当数据表记录在千万以上时,select count(1) from table /// 的速度会受到影响,所以扩展一个方法解决这个问题 /// </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> /// 数据总数 /// </summary> int DataTotalCount = 0; /// <summary> /// 数据总页数 /// </summary> int DataTotalPages = 0; /// <summary> /// 数据页面大小(每次向数据库提交的记录数) /// </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();//对象无法自动添加到上下文中,因为它是使用 NoTracking 合并选项检索的。请在定义此关系之前,将该实体显式附加到 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;//建立指定类型的实例 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;//永不超时 _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> /// 根据工作单元的IsUnitOfWork的属性,去判断是否提交到数据库 /// 一般地,在多个repository类型进行组合时,这个IsUnitOfWork都会设为true,即不马上提交, /// 而对于单个repository操作来说,它的值不需要设置,使用默认的false,将直接提交到数据库,这也保证了操作的原子性。 /// </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)//如果没有定义日志功能,就把异常抛出来吧 throw ex; Logger(ex.Message); } } /// <summary> /// 计数更新,与SaveChange()是两个SQL链接,走分布式事务 /// 子类可以根据自己的逻辑,去复写 /// tableName:表名 /// param:索引0为主键名,1表主键值,2为要计数的字段,3为增量 /// </summary> /// <param name="tableName">表名</param> /// <param name="param">参数列表,索引0为主键名,1表主键值,2为要计数的字段,3为增量</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> /// 分页进行数据提交的逻辑 /// </summary> /// <param name="item">原列表</param> /// <param name="method">处理方法</param> /// <param name="currentItem">要进行处理的新列表</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> /// 得到实体键EntityKey /// </summary> /// <typeparam name="TEntity"></typeparam> /// <returns></returns> protected ReadOnlyMetadataCollection<EdmMember> GetPrimaryKey() { EntitySetBase primaryKey = ((IObjectContextAdapter)_Db).ObjectContext.GetEntitySet(typeof(TEntity)); ReadOnlyMetadataCollection<EdmMember> arr = primaryKey.ElementType.KeyMembers; return arr; } /// <summary> /// 构建Update语句串 /// 注意:如果本方法过滤了int,decimal类型更新为0的列,如果希望更新它们需要指定FieldParams参数 /// </summary> /// <param name="entity">实体列表</param> /// <param name="fieldParams">要更新的字段</param> /// <returns></returns> private Tuple<string, object[]> CreateUpdateSQL(Expression<Action<TEntity>> expression) { TEntity entity = typeof(TEntity).GetConstructor(Type.EmptyTypes).Invoke(null) as TEntity;//建立指定类型的实例 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语句串 /// 注意:如果本方法过滤了int,decimal类型更新为0的列,如果希望更新它们需要指定FieldParams参数 /// </summary> /// <param name="entity">实体列表</param> /// <param name="fieldParams">要更新的字段</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)//过滤导航属性 && (i.PropertyType.IsValueType || i.PropertyType == typeof(string)) ).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(); 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("没有任何属性进行更新"); 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语句串 /// 主键为自增时,如果主键值为0,我们将主键插入到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();//过滤主键,航行属性,状态属性等 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操作的类型 /// </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,根据SQL操作的类型 /// </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("请输入正确的参数"); } return sqlstr.ToString(); } /// <summary> /// SQL操作类型 /// </summary> protected enum SQLType { /// <summary> /// 更新传入的实体代码去添加 /// </summary> Insert, /// <summary> /// 根据传入的实体列表去更新 /// </summary> Update, /// <summary> /// 根据传入的实体列表去删除 /// </summary> Delete, } #endregion }扩展:基础设施层 / 系统架构 基础设施层 / ddd 防腐层
下面看一下对于基础设施层所依赖的程序集
可以看到,它主要依赖于领域实体层与领域实体规约层。
OK,对于基础设施层的搭建就说到这,下回我们将说一下领域层的搭建。
回到目录
扩展:基础设施层 / 系统架构 基础设施层 / ddd 防腐层
三 : 含山县:含山县-基础设施,含山县-县名由来
四 : 迅雷布局基础设施领域 数据加速再扩张
近期,迅雷宣布推出上网加速器,可以将家用物理宽带进行大幅提升。众所周知,迅雷的高速通道和离线下载一直都是用户最为欢迎的网络数据加速服务,而通过技术手段提升家用物理带宽则是一次突破性的创新。
据了解,迅雷上网加速器是迅雷与电信合作推出的一项上网加速服务,其技术原理是将用户现有物理宽带提高,让上网速度更快。相关数据显示,迅雷上网加速器最高可将电信家用宽带提升至30Mbps。
事实上,除了自己推出的各项云加速相关服务之外,迅雷很早就与电信运营商建立了合作关系,希望通过加大用户的物理带宽进一步提升用户上网体验,这样也能帮助迅雷获取更多的付费订阅会员数量。迅雷的付费订阅收入是迅雷最重要的收入来源之一,而更好的上网体验则是其中的关键。迅雷一直以来也在互联网基础设施方面积极创新并加大投入。
此前,迅雷推出了“迅雷水晶”功能,该功能可以让互联网家庭用户贡献自己的闲置带宽,并获得相应的收益和回报。同时,迅雷可以有效利用用户挂机所贡献的闲余带宽,优化自身的服务体验,让数据传输速度变得更快,视频观看更流畅。
今年9月,迅雷还收购了金山快盘个人版业务,金山快盘一直都是小米移动用户的云存储服务提供商,迅雷将利用自身的加速技术来改善快盘用户体验,并为付费用户提供更高水平的速度和服务。
迅雷在市场竞争中依靠的是独特的技术实力和巨大的基础设施投入。根据此前公开资料显示,迅雷拥有的内容索引高达60亿,在全国重要城市部署的云加速服务器(包括租赁和自有)多达近万台。
迅雷在基础设施方面的投入和强大实力正在帮助他们更好的提升用户上网体验。根据迅雷日前发布的第三季度财报显示,其在第三季度的订阅服务营收为2490万美元,同比增长8.4%。同比增长主要是由于订阅服务用户数量从去年同期的440万人增加到510万人,增幅为15.6%。而在持续增长的订阅用户数量保障下,迅雷或许将迎来下一个收入高峰。
本文标题:基础设施-保护基础设施和水系规划首设“黄线”“蓝线”61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1