C#递归应用之实现JS文件的自动引用
作者:hztech 发布时间:2023-12-09 00:03:52
背景
两张表,分别是 :sys_tbl,和 sys_field,其中:sys_tbl 是系统所有表的信息,包含两个字段 :code(表名),name(表描述信息);sys_fld 是记录第张表中的字段 的名称(field)和描述信息(table) ,
截图如下:
sys_tbl
其中,字段 名称包含对其它名称(对象) 的引用,写法为:表名(去除下划线)_引用字段 ,如:einventory_cinvcode,就是对表 e_inventory 中字段 cinvcode的引用。
每张表都在系统 中对应有不同功能的js文件(模块)如: 编辑窗体(dialog类型),跨域选择窗体(field)类型等
需求
在一个综合的页面中,会对其它对象进行引用(依赖),而这种引用最终体现在对js文件的包含。同时被引用的js 文件(一级引用)还有自已关联对象(二级引用).....如此下去,直到N 级引用。
所以现在需要逐层找到对象的引用,直到最后不依赖任何对象为止,并把这些js文件生成引用包含路径(不重复)
分析
1、返回结果类型
得到这些js引用,不能重复,但是对象之间引用是可以存在交叉的,在整个引用链条上,同一个对象会被 多个对象引用,所以简单的字符串数组是避免不了重复的。但是在C#中的HashSet可以做到不重复,同时这个去重工作是自动完成的,所以存结果如果是简单的value类型,用 HashSet就可以,但是因为字段中表的信息已经被格式化过,所以还要把格式化之前的表名称取出与字段对应,所以需要一个key-value类型的数据 ,那就是 Dictionary<string, string> 了。
2、算法选择
因为查找引用,是层层进行的,而且下一层引用的要用到上一层的引用结果,所以这里选择递归算法
代码实现
声明一个全局变量,记录所有的表与字段的对应的数据,因为需要确保数据key 唯一性所以选择Dicctionary类型
/// <summary>
/// define the gloable parameter to save the rel obj data
/// </summary>
public static Dictionary<string, string> <strong>deepRef </strong>= new Dictionary<string, string>();
入口函数,完成准备工作,(数据库连接,参数准备)
/// <summary>
/// 通过表的字段 获取相关的引用字段依赖的对象 直到没有依赖为止
/// </summary>
/// <param name="headField">表字段列表</param>
/// <returns></returns>
public static Dictionary<string,string> getRelRef(List<IniItemsTableItem> headField)
{
HashSet<string> refset = new HashSet<string>();
// HashSet<string> refset_result = new HashSet<string>();
foreach (var item in headField)
{
if (!item.controlType.StartsWith("hz_"))// is not the field of reference
{
continue;
}
string[] fieldarr = item.dataIndex.Split('_');//the constructor is :[tabble]_[field]
refset.Add(fieldarr[0]);//the first prefix
}
dataOperate dao = new dataOperate();
dao.DBServer = "info";
SqlConnection conn = dao.createCon();
try
{
if (refset.Count > 0)
{
if (conn.State != ConnectionState.Open)
conn.Open();//open connection
deepRef = new Dictionary<string, string>();//clear the relation obj data
getRef(conn, refset);
}
return deepRef;
}
catch (Exception)
{
throw;
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
}
}
递归函数,最终完成在数据库中获取字段依赖的对象的获取
/// <summary>
/// get the relation obj
/// </summary>
/// <param name="conn"></param>
/// <param name="ref_field"></param>
/// <returns></returns>
public static HashSet<string> <strong>getRef</strong>(SqlConnection conn, HashSet<string> ref_field)
{
HashSet<string> refset = new HashSet<string>();
string refstr = string.Join("','", ref_field);
if (refstr != "")
{
refstr = "'" + refstr + "'";
string sql = "SELECT dbo.GetSplitOfIndex(b.[field],'_',1) as refcode,a.[code] FROM ( select replace(code,'_','') as uncode,* from [SevenWOLDev].[dbo].[sys_tbl_view] ) as a inner join [SevenWOLDev].[dbo].[sys_fld_view] as b on a.uncode=dbo.GetSplitOfIndex(b.[field],'_',1) where replace([table],'_','') in (" + refstr + ") and uitype='ref'";
//get dataset relation obj
DataSet ds = dataOperate.getDataset(conn, sql);
if (ds != null && ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
if (dt.Rows.Count > 0)
{
//rel ref exists
for (int k = 0; k < dt.Rows.Count; k++)
{
string vt = dt.Rows[k].ItemArray[0].ToString();
string vv = dt.Rows[k].ItemArray[1].ToString();
refset.Add(vt);//save current ref
if(!<strong>deepRef</strong>.ContainsKey(vt))
<strong>deepRef</strong>.Add(vt, vv);// save all ref
}
if (refset.Count > 0)// get the ref successfully
{
//recursion get
getRef(conn, refset);
}
}
}
}
else
{
//no ref
}
return refset;
}
对函数进行调用,并组织出js文件引用路径
Dictionary<string,string> deepRef = ExtjsFun.getRelRef(HeadfieldSetup);
if (deepRef != null)
{
foreach (var s in deepRef)
{
string tem_module = "";
tem_module = s.Value;
string[] moduleArr = tem_module.Split('_');
if (tem_module.IndexOf("_") >= 0)
tem_module = moduleArr[1];//module name for instance: p_machine ,the module is “machine” unless not included the underscore
string fieldkind = "dialog";
jslist.Add(MyComm.getFirstUp(tem_module) + "/" + ExtjsFun.GetJsModuleName(tem_module, s.Value, fieldkind) + ".js");
fieldkind = "field";
jslist.Add(MyComm.getFirstUp(tem_module) + "/" + ExtjsFun.GetJsModuleName(tem_module, s.Value, fieldkind) + ".js");
}
}
最终结果 如下:
<script src="../../dept/demoApp/scripts/Sprice/SpriceE_spriceGridfield.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Org/OrgE_orgDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Supplier/SupplierOa_supplierDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Supplier/SupplierOa_supplierField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Unit/UnitE_unitDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Unit/UnitE_unitField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Wh/WhWh_whDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Wh/WhWh_whField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Mold/MoldP_moldDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Mold/MoldP_moldField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Suppliercategory/SuppliercategoryOa_suppliercategoryDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Suppliercategory/SuppliercategoryOa_suppliercategoryField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Bank/BankOa_bankDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Bank/BankOa_bankField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Machine/MachineP_machineDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Machine/MachineP_machineField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Inventory/InventoryE_inventoryDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Basedocment/BasedocmentOa_basedocmentDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Basedocment/BasedocmentOa_basedocmentField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Basedoctype/BasedoctypeOa_basedoctypeDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Basedoctype/BasedoctypeOa_basedoctypeField.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Tax/TaxE_taxDialog.js" type="text/javascript"></script>
<script src="../../dept/demoApp/scripts/Tax/TaxE_taxField.js" type="text/javascript"></script>
完事代码如下:
/// <summary>
/// define the gloable parameter to save the rel obj data
/// </summary>
public static Dictionary<string, string> deepRef = new Dictionary<string, string>();
/// <summary>
/// 通过表的字段 获取相关的引用字段依赖的对象 直到没有依赖为止
/// </summary>
/// <param name="headField">表字段列表</param>
/// <returns></returns>
public static Dictionary<string,string> getRelRef(List<IniItemsTableItem> headField)
{
HashSet<string> refset = new HashSet<string>();
// HashSet<string> refset_result = new HashSet<string>();
foreach (var item in headField)
{
if (!item.controlType.StartsWith("hz_"))// is not the field of reference
{
continue;
}
string[] fieldarr = item.dataIndex.Split('_');//the constructor is :[tabble]_[field]
refset.Add(fieldarr[0]);//the first prefix
}
dataOperate dao = new dataOperate();
dao.DBServer = "info";
SqlConnection conn = dao.createCon();
try
{
if (refset.Count > 0)
{
if (conn.State != ConnectionState.Open)
conn.Open();//open connection
deepRef = new Dictionary<string, string>();//clear the relation obj data
getRef(conn, refset);
}
return deepRef;
}
catch (Exception)
{
throw;
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
}
}
/// <summary>
/// get the relation obj
/// </summary>
/// <param name="conn"></param>
/// <param name="ref_field"></param>
/// <returns></returns>
public static HashSet<string> getRef(SqlConnection conn, HashSet<string> ref_field)
{
HashSet<string> refset = new HashSet<string>();
string refstr = string.Join("','", ref_field);
if (refstr != "")
{
refstr = "'" + refstr + "'";
string sql = "SELECT dbo.GetSplitOfIndex(b.[field],'_',1) as refcode,a.[code] FROM ( select replace(code,'_','') as uncode,* from [SevenWOLDev].[dbo].[sys_tbl_view] ) as a inner join [SevenWOLDev].[dbo].[sys_fld_view] as b on a.uncode=dbo.GetSplitOfIndex(b.[field],'_',1) where replace([table],'_','') in (" + refstr + ") and uitype='ref'";
//get dataset relation obj
DataSet ds = dataOperate.getDataset(conn, sql);
if (ds != null && ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
if (dt.Rows.Count > 0)
{
//rel ref exists
for (int k = 0; k < dt.Rows.Count; k++)
{
string vt = dt.Rows[k].ItemArray[0].ToString();
string vv = dt.Rows[k].ItemArray[1].ToString();
refset.Add(vt);//save current ref
if(!deepRef.ContainsKey(vt))
deepRef.Add(vt, vv);// save all ref
}
if (refset.Count > 0)// get the ref successfully
{
//recursion get
getRef(conn, refset);
}
}
}
}
else
{
//no ref
}
return refset;
}
来源:https://www.cnblogs.com/hztech/p/17202728.html


猜你喜欢
- OpenCv提供了函数 findContours()用于对物体轮廓进行检测,该函数实现算法是由S.suzuki K.Abe于1985年发表的
- 前言:在看这个变更之前,我们需要回忆下 Android 12 的一个安全性变更, 即声明了 <intent-filter&g
- 最近要做一个网站,要求实现验证码程序,经过不断调试,终于成功实现功能。一、验证码生成类生成验证码的话需要用到java的Graphics类库,
- /// <summary> /// interface &
- Java调用天气Webservice的小应用废话不多说,直接贴代码: CityReq.javapackage com.weathe
- 最近项目中需要实现定时执行任务,比如定时计算会员的积分、调用第三方接口等,由于项目采用spring框架,所以这里结合spring框架来介绍。
- 一、场景笔者就Zuul网关下实现其负载均衡与熔断机制(雪崩)进行实践,前提是已经导入zuul相关依赖springboot版本:1.5.9.R
- 本文实例讲述了C#检查字符串是否是合法URL地址的方法。分享给大家供大家参考。具体实现方法如下:protected string HTTPC
- 本文实例讲述了C#获取进程或线程相关信息的方法。分享给大家供大家参考。具体实现方法如下:using System;using System.
- 内存对齐的基本原则:结构(struct/class)的内置类型数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的起始位置
- 单例模式的实现(5种)常用:饿汉式(线程安全,调用效率高,但是不能延时加载)懒汉式(线程安全,调用效率不高,可以延时加载)其他:双重检测锁式
- 前言:先写个简单的地点签到功能,如果日后有时间细写的话,会更加好好研究一下百度地图api,做更多逻辑判断。这里主要是调用百度地图中的场景定位
- 一、万能的字符串当然,任何时候都可以使用字符串作为属性的值,从配置文件里读取出来,如下:配置文件内容为:pkslow.admin=larry
- C#中的泛型和反射经常是一起工作的,因此这里就一次性的加以介绍了。由于c#是强类型语言,一般来说函数的返回类型和参数的类型都是一早写好的,这
- 想做一个APP,设计中有侧边栏这个功能,所以现在开始学习下侧边栏的实现。在官方的UI空间中已经给出了DrawerLayout这个侧滑的菜单空
- 用户可以自定义打印某一年的年历,即:把某一年的日历全部打印出来如把2013年的年历打印出来如下:January 2013&nbs
- 关于java图片验证码的文章最近更新了不少,帮助大家掌握java验证码的生成技术,下文为大家分享了java生成图片验证码最简单的方法,供大家
- 本文实例为大家分享了MVPXlistView上拉下拉展示的具体代码,供大家参考,具体内容如下抽基类package com.gs.gg.day
- 本项目为大家分享了Java实现简单计算器功能的具体代码,供大家参考,具体内容如下一 项目说明实训目的:掌握 Java GUI 开发中的布局管
- 前言在之前的项目中,有做过一个需求,需要实现一个颜色渐变的折线图。当时项目中使用的图表库是MPAndroidChart,但是该库没有提供合适