コード例 #1
0
        /// <summary>
        ///		<para>从指定的表标识对应的实体开始进行路径展开。</para>
        ///		<para>注:展开过程包括对父实体的属性集的搜索。</para>
        /// </summary>
        /// <param name="table">指定的进行展开的起点。</param>
        /// <param name="path">指定要展开的成员路径,支持多级导航属性路径。</param>
        /// <param name="step">指定路径中每个属性的展开回调函数。</param>
        /// <returns>返回找到的结果。</returns>
        public static ReduceResult Reduce(this TableIdentifier table, string path, Func <ReduceContext, ISource> step = null)
        {
            if (table == null)
            {
                throw new ArgumentNullException(nameof(table));
            }

            if (table.Entity == null)
            {
                throw new DataException($"The '{table}' table cannot be expanded.");
            }

            if (string.IsNullOrEmpty(path))
            {
                return(ReduceResult.Failure(table));
            }

            ICollection <IEntityMetadata> ancestors = null;
            IEntityPropertyMetadata       property  = null;
            ISource token      = table;
            var     parts      = path.Split('.');
            var     properties = table.Entity.Properties;

            for (int i = 0; i < parts.Length; i++)
            {
                if (properties == null)
                {
                    return(ReduceResult.Failure(token));
                }

                //如果当前属性集合中不包含指定的属性,则尝试从父实体中查找
                if (!properties.TryGet(parts[i], out property))
                {
                    //尝试从父实体中查找指定的属性
                    property = FindBaseProperty(ref properties, parts[i], ref ancestors);

                    //如果父实体中也不含指定的属性则返回失败
                    if (property == null)
                    {
                        return(ReduceResult.Failure(token));
                    }
                }

                //如果回调函数不为空,则调用匹配回调函数
                //注意:将回调函数返回的结果作为下一次的用户数据保存起来
                if (step != null)
                {
                    token = step(new ReduceContext(string.Join(".", parts, 0, i), token, property, ancestors));
                }

                //清空继承实体链
                if (ancestors != null)
                {
                    ancestors.Clear();
                }

                if (property.IsSimplex)
                {
                    break;
                }
                else
                {
                    properties = GetAssociatedProperties((IEntityComplexPropertyMetadata)property, ref ancestors);
                }
            }

            //返回查找到的结果
            return(new ReduceResult(token, property));
        }