Ejemplo n.º 1
0
        /// <summary>
        /// 生成新的全名,以参考节点的全名作为基础
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        private string GenerateFullName(EntityTreeUpfydatingArgument arg1, EntityTreeUpfydatingArgument arg2, EntityTreePosition position)
        {
            var fullName = string.Empty;

            if (metaTree.Name == null || metaTree.FullName == null)
            {
                return(null);
            }

            //没有参考节点,则使用名称
            if (arg2 == null)
            {
                fullName = arg1.NewValue.Name;
            }
            else
            {
                //获得参考节点的全名
                fullName = arg2.NewValue.FullName;
                if (position != EntityTreePosition.Children)
                {
                    //取前面一级的全名
                    fullName = GetPreviousFullName(fullName);
                }

                //拼接上当前的名称
                fullName = string.Format("{0}{1}{2}", fullName, metaTree.NameSeparator, arg1.NewValue.Name);
            }

            return(fullName);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 使用 <see cref="EntityTreeUpfydatingArgument"/> 更新实体属性。
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="argument"></param>
        /// <param name="force">是否强制修改。</param>
        private void UpdateEntityByArgument(IEntity entity, EntityTreeUpfydatingArgument argument, bool force = false)
        {
            //force强制修改属性
            if (force || argument.OldValue.InnerId != argument.NewValue.InnerId)
            {
                entity.SetValue(metaTree.InnerSign, argument.NewValue.InnerId);
            }

            if (metaTree.Level != null &&
                (force || argument.OldValue.Level != argument.NewValue.Level))
            {
                entity.SetValue(metaTree.Level, argument.NewValue.Level);
            }

            if (metaTree.Order != null &&
                (force || argument.OldValue.Order != argument.NewValue.Order))
            {
                entity.SetValue(metaTree.Order, argument.NewValue.Order);
            }

            if (metaTree.Name != null &&
                (force || argument.OldValue.Name != argument.NewValue.Name))
            {
                entity.SetValue(metaTree.Name, argument.NewValue.Name);
            }

            if (metaTree.FullName != null &&
                (force || argument.OldValue.FullName != argument.NewValue.FullName))
            {
                entity.SetValue(metaTree.FullName, argument.NewValue.FullName);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 获取孩子、孙子、重孙...。
        /// </summary>
        /// <param name="argument"></param>
        /// <param name="isolation"></param>
        /// <returns></returns>
        private IEnumerable <TEntity> GetChildren(EntityTreeUpfydatingArgument argument, Expression <Func <TEntity> > isolation = null)
        {
            var expression = TreeExpressionBuilder.BuildGetChildrenExpression <TEntity>(metaTree, argument.OldValue.InnerId);

            var querable = QueryHelper.CreateQuery <TEntity>(repository.Provider, expression);

            expression = TreeExpressionBuilder.AddIsolationExpression <TEntity>(querable.Expression, isolation);
            expression = TreeExpressionBuilder.AddUseableSelectExpression <TEntity>(metaTree, expression);

            return(repository.Provider.CreateQuery <TEntity>(expression).ToList());
        }
Ejemplo n.º 4
0
        private void UpdateChildren(TEntity current, IEnumerable <TEntity> entities, EntityTreeUpfydatingArgument argument)
        {
            foreach (var entity in entities)
            {
                var arg = CreateUpdatingArgument(entity);

                arg.NewValue.Level   = argument.NewValue.Level + arg.OldValue.Level - argument.OldValue.Level;
                arg.NewValue.InnerId = argument.NewValue.InnerId + arg.OldValue.InnerId.Substring(argument.OldValue.Level * metaTree.SignLength);

                if (metaTree.FullName != null && !string.IsNullOrEmpty(argument.NewValue.FullName))
                {
                    arg.NewValue.FullName = argument.NewValue.FullName + metaTree.NameSeparator + GetRightFullName(arg.OldValue.FullName, argument.OldValue.Level);
                }

                UpdateEntityByArgument(entity, arg);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 将子节点移动到另一个子节点的下面。
        /// </summary>
        /// <param name="current"></param>
        /// <param name="referEntity"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="isolation"></param>
        private void UpdateMoveAsChildren(TEntity current, TEntity referEntity, EntityTreeUpfydatingArgument arg1, EntityTreeUpfydatingArgument arg2, Expression <Func <TEntity> > isolation = null)
        {
            //获取要移动节点的兄弟及其孩子
            var brothers = GetBrothersAndChildren(arg1, false, null, isolation: isolation);

            //获取要移动的节点的孩子
            var children = GetChildren(arg1, isolation);

            //兄弟及其孩子要下移一个单位
            UpdateBrothersAndChildren(current, brothers, arg1.OldValue.InnerId, -1);

            //获得新节点的Order值
            arg1.NewValue.Order = GetNewOrderNumber(arg2.OldValue, EntityTreePosition.Children, isolation: isolation);

            var modify = IsInList(referEntity, brothers);

            if (modify != null)
            {
                arg2 = CreateUpdatingArgument(modify);
            }

            var keyId = arg2.OldValue.InnerId;

            //获得参照节点的级别
            arg1.NewValue.Level = arg2.OldValue.Level + 1;

            //生成新的InnerID
            arg1.NewValue.InnerId  = GenerateInnerId(keyId, arg1.NewValue.Order, EntityTreePosition.Children);
            arg1.NewValue.FullName = GenerateFullName(arg1, arg2, EntityTreePosition.Children);

            //更新要移动的节点的孩子
            UpdateChildren(current, children, arg1);
            UpdateEntityByArgument(current, arg1);

            SetNameNotModified(new[] { current });
            SetNameNotModified(brothers);
            SetNameNotModified(children);

            repository.Update(current);

            repository.Batch(brothers, (u, s) => u.Update(s));
            repository.Batch(children, (u, s) => u.Update(s));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 节点移动到根目录下,相关节点的更新。
        /// </summary>
        /// <param name="current"></param>
        /// <param name="arg"></param>
        /// <param name="isolation"></param>
        /// <param name="cancellationToken">取消操作的通知。</param>
        private async Task UpdateMoveToRootAsync(TEntity current, EntityTreeUpfydatingArgument arg, Expression <Func <TEntity> > isolation = null, CancellationToken cancellationToken = default)
        {
            //获得新节点的Order值
            var newOrder = GetNewOrderNumber(null, EntityTreePosition.Children, isolation: isolation);

            //获取它的兄弟及其孩子
            var brothers = GetBrothersAndChildren(arg, false, null, isolation: isolation);

            //获取它的孩子
            var children = GetChildren(arg, isolation);

            //生成新的InnerID
            var currentInnerId = GenerateInnerId(string.Empty, newOrder, EntityTreePosition.Children);

            //全名即为名称
            if (metaTree.FullName != null && metaTree.Name != null)
            {
                arg.NewValue.FullName = arg.OldValue.Name;
            }

            arg.NewValue.InnerId = currentInnerId;
            arg.NewValue.Level   = 1;
            arg.NewValue.Order   = newOrder;

            UpdateEntityByArgument(current, arg);

            //兄弟及其孩子要上移一个单位
            UpdateBrothersAndChildren(current, brothers, string.Empty, -1);

            //它的孩子要移到根节点下
            UpdateChildren(current, children, arg);

            SetNameNotModified(new[] { current });
            SetNameNotModified(brothers);
            SetNameNotModified(children);

            await repository.UpdateAsync(current);

            await repository.BatchAsync(brothers, (u, s) => u.Update(s));

            await repository.BatchAsync(children, (u, s) => u.Update(s));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 节点移动到根目录下,相关节点的更新。
        /// </summary>
        /// <param name="current"></param>
        /// <param name="arg"></param>
        /// <param name="isolation"></param>
        private void UpdateMoveToRoot(TEntity current, EntityTreeUpfydatingArgument arg, Expression <Func <TEntity> > isolation = null)
        {
            //获得新节点的Order值
            var newOrder = GetNewOrderNumber(null, EntityTreePosition.Children, isolation: isolation);

            //获取它的兄弟及其孩子
            var brothers = GetBrothersAndChildren(arg, false, null, isolation: isolation);

            //获取它的孩子
            var children = GetChildren(arg, isolation);

            //生成新的InnerID
            var currentInnerId = GenerateInnerId(string.Empty, newOrder, EntityTreePosition.Children);

            //全名即为名称
            if (metaTree.FullName != null && metaTree.Name != null)
            {
                arg.NewValue.FullName = arg.OldValue.Name;
            }

            arg.NewValue.InnerId = currentInnerId;
            arg.NewValue.Level   = 1;
            arg.NewValue.Order   = newOrder;

            UpdateEntityByArgument(current, arg);

            //兄弟及其孩子要上移一个单位
            UpdateBrothersAndChildren(current, brothers, currentInnerId, -1);

            //它的孩子要移到根节点下
            UpdateChildren(current, children, arg);

            repository.Update(current);

            repository.Batch(brothers, (u, s) => u.Update(s));
            repository.Batch(children, (u, s) => u.Update(s));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 获取兄弟及他们的孩子。
        /// </summary>
        /// <param name="argument"></param>
        /// <param name="includeCurrent">是否包含当 <paramref name="argument"/>,当在它前面插入时,需要包含它。</param>
        /// <param name="excludeArg">要排除的实体。</param>
        /// <param name="isTop">是否遇到要排除的实体就终止。</param>
        /// <param name="isolation"></param>
        /// <returns></returns>
        private IEnumerable <TEntity> GetBrothersAndChildren(EntityTreeUpfydatingArgument argument, bool includeCurrent, EntityTreeUpfydatingArgument excludeArg, bool isTop = false, Expression <Func <TEntity> > isolation = null)
        {
            var keyId      = argument.OldValue.InnerId;
            var order      = argument.OldValue.Order;
            var level      = argument.OldValue.Level;
            var parameters = new ParameterCollection();
            var m          = EntityMetadataUnity.GetEntityMetadata(entityType);

            var sb = new StringBuilder();

            sb.Append("SELECT ");
            var assert = new AssertFlag();

            foreach (var property in GetUseableProperties())
            {
                if (property == null)
                {
                    continue;
                }

                if (!assert.AssertTrue())
                {
                    sb.Append(", ");
                }

                sb.AppendFormat("t.{0} {0}", QuoteColumn(property));
            }

            sb.AppendFormat(" FROM {0} t", GetTableName());
            sb.AppendFormat(" JOIN (SELECT f.{0} {0} FROM {1} f", QuoteColumn(metaTree.InnerSign), GetTableName());

            sb.AppendFormat(" WHERE {0} LIKE {1} AND {5} = {6} AND {2} {4} {3}", QuoteColumn(metaTree.InnerSign), syntax.FormatParameter("pn"),
                            GetOrderExpression(), order, includeCurrent ? ">=" : ">", GetLevelExpression(), level);

            if (m.DeleteProperty != null)
            {
                sb.AppendFormat(" AND {0} = {1}", QuoteColumn(m.DeleteProperty), 0);
            }

            if (excludeArg != null)
            {
                var excludeId = excludeArg.OldValue.InnerId;
                sb.AppendFormat(" AND NOT ({0} LIKE {1})", QuoteColumn(metaTree.InnerSign), syntax.FormatParameter("px"));
                parameters.Add("px", excludeId + "%");

                if (isTop)
                {
                    sb.AppendFormat(" AND {0} < {1}", QuoteColumn(metaTree.InnerSign), syntax.FormatParameter("px1"));
                    parameters.Add("px1", excludeId);
                }
            }

            if (!includeCurrent)
            {
                sb.AppendFormat(" AND {0} <> {1}", QuoteColumn(metaTree.InnerSign), syntax.FormatParameter("pm"));
                parameters.Add("pm", keyId);
            }

            var conIsolation = string.Empty;

            if (isolation != null)
            {
                conIsolation = IsolationConditionBuilder.Build(isolation);
                if (!string.IsNullOrEmpty(conIsolation))
                {
                    sb.AppendFormat(" AND {0}", conIsolation);
                }
            }

            sb.AppendFormat(") f ON t.{0} LIKE {1}", QuoteColumn(metaTree.InnerSign), syntax.String.Concat("f." + QuoteColumn(metaTree.InnerSign), "'%'"));

            if (!string.IsNullOrEmpty(conIsolation))
            {
                sb.AppendFormat(" WHERE {0}", conIsolation);
            }

            sb.AppendFormat("ORDER BY {0}", QuoteColumn(metaTree.InnerSign));

            keyId = GetPreviousKey(keyId) + "_%";
            parameters.Add("pn", keyId);

            return(database.ExecuteEnumerable((SqlCommand)sb.ToString(), parameters: parameters, rowMapper: new EntityRowMapper <TEntity>()).ToList());
        }
Ejemplo n.º 9
0
        /// <summary>
        /// 构造获取兄弟节点及孩子的表达式。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="metadata"></param>
        /// <param name="argument"></param>
        /// <param name="includeCurrent"></param>
        /// <param name="excludeArg"></param>
        /// <param name="isTop"></param>
        /// <returns></returns>
        internal static Expression BuildGetBrothersAndChildrenExpression <T>(EntityTreeMetadata metadata, EntityTreeUpfydatingArgument argument, bool includeCurrent, EntityTreeUpfydatingArgument excludeArg, bool isTop = false)
        {
            var parExp    = Expression.Parameter(typeof(T), "s");
            var memberExp = Expression.MakeMemberAccess(parExp, metadata.InnerSign.Info.ReflectionInfo);

            return(null);
        }