Пример #1
0
        /// <summary>
        /// 获取表连接时子表的明细数据
        /// </summary>
        /// <param name="col"></param>
        /// <param name="drs"></param>
        /// <returns></returns>
        private JArray GetChildItems(FieldMeta col, IEnumerable <DataRow> drs)
        {
            var    childModel = _ms.GetTableMeta(col.ArrayItemType);
            JArray childDt    = new JArray();

            //找到ForeignKey定义中的别名
            string alias   = null;
            var    aliases = col.ForeignKey.Split('.');

            if (aliases.Length > 1)
            {
                alias = aliases[0];
            }

            foreach (var dr in drs)
            {
                var  newDr    = new JObject();
                bool hasValue = false;
                foreach (FieldMeta fm in childModel.Fields)
                {
                    var bm = $"{alias ?? childModel.Name}_{fm.Name}";
                    if (dr[bm] != DBNull.Value)
                    {
                        hasValue = true;
                    }
                    newDr[fm.Name] = new JValue(dr[bm]);
                }
                //忽略全部是空的行,这在左连接时经常发生
                if (hasValue)
                {
                    childDt.Add(newDr);
                }
            }
            return(childDt);
        }
Пример #2
0
        /// <summary>
        /// 获取表连接时子表的明细数据,递归执行
        /// </summary>
        /// <param name="col"></param>
        /// <param name="drList"></param>
        /// <returns></returns>
        private JArray GetChildItems(FieldMeta col, IEnumerable <DataRow> drList)
        {
            JArray childDt = new JArray();

            if (++_deep > 8)
            {
                return(childDt);             //防止递归层次过多
            }
            if (drList.IsEmpty())
            {
                return(childDt);
            }

            var dt         = drList.First().Table;
            var childTable = _ms.GetTableMeta(col.ArrayItemType);
            var pkeys      = childTable.PrimaryKeys;

            //找到ForeignKey定义中的别名
            string alias   = null;
            var    aliases = col.ForeignKey.Split('.');

            if (aliases.Length > 1)
            {
                alias = aliases[0];
            }

            //当从表的主键字段在数据集中找不到时,说明没有联接此从表
            if (pkeys.Any(pkey =>
            {
                var pkeyAlias = $"{alias ?? childTable.Name}_{pkey.Name}";
                return(!dt.Columns.Contains(pkeyAlias));
            }))
            {
                return(childDt);
            }

            var getPKeyValues = new Func <DataRow, string>(dr =>
            {
                var keyValues = pkeys.Select(pkey =>
                {
                    var pkeyAlias = $"{alias ?? childTable.Name}_{pkey.Name}";
                    return(dr[pkeyAlias].ToString());
                });
                return(String.Join("^", keyValues));
            });

            //查询主子表中不重复的主键字段值
            var keyRowRroups = drList
                               .GroupBy(dr => getPKeyValues(dr))
                               .Where(kv => kv.Key.IsNotEmpty()).ToList();

            keyRowRroups.Each(drs =>
            {
                var newRow = new JObject();

                //遍历主表的每个字段,找出各类字段定义
                childTable.Fields.Each(fm =>
                {
                    var bm = $"{alias ?? childTable.Name}_{fm.Name}";

                    if (fm.IsArray)
                    {
                        newRow[fm.Name] = GetChildItems(fm, drs);
                        return;
                    }
                    else if (fm.DataType == Consts.OperatorUIType)
                    {
                        return;
                    }
                    if (fm.ForeignField.IsEmpty() && !dt.Columns.Contains(bm))
                    {
                        return;
                    }

                    var firstDr     = drs.First();
                    newRow[fm.Name] = new JValue(firstDr[bm]);
                });
                childDt.Add(newRow);
            });
            _deep--;
            return(childDt);
        }