/// <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); }
/// <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); }