c#所有部门及其下所部门生成树形图(递归算法获取或键值对方式获取)
部门数据库的设计:
代码:
/// <summary>
/// 获取部门(入口)
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("GetDepart")]
public ResultEntity<List<JieDian>> GetDepart()
{
ResultEntity<List<JieDian>> result = new ResultEntity<List<JieDian>>();
int? officeId = ;
try
{
officeId = new AuthInfo().GetOfficeId(User as ClaimsPrincipal);
if (!officeId.HasValue)
{
result.IsSuccess = false;
result.ErrorCode = ;
result.Msg = "未登录或已过期";
return result;
}
ProvinceMeetCase meetCase = new ProvinceMeetCase();
var data = meetCase.creatTree();
result.Data = data;
result.IsSuccess = true;
result.Msg = "部门获取成功";
}
catch (Exception e)
{
result.ErrorCode = ;
result.Msg = e.ToString();
} return result;
}
第一种解决方案(递归):
//生成树的方法
public List<JieDian> creatTree()
{
List<JieDian> result = new List<JieDian>();
try
{
using (var container = new TRA_EXTContainer())
{
string sql = string.Format(@"SELECT a.Name [DepartName],a.Id [DepartId]
FROM [HYSYZSCCODB].[dbo].[Department] a
where a.IsValid='true' and a.Level = 1");
//这里改成你的数据库表
var data = container.Database.SqlQuery<DepartDTO>(sql).ToList(); //这里我直接调用了我库中的类
foreach (var item in data)
{
JieDian jd = new JieDian();
jd.Id = item.DepartId;
jd.Name = item.DepartName;
var d = creatTheTree(item.DepartId, jd);
if (d == null)
{
result.Add(jd);
continue;
}
result.Add(d);
}
}
}
catch (Exception e)
{
throw e;
} return result;
} //生成树的方法(自身方法不断循环)
public JieDian creatTheTree(Guid parentId, JieDian jd)
{
//获取
DepartDTO[] items = GetTheItems(parentId);
//如果没有字节点了,那就返回空
if (items.Length == )
return null;
List<JieDian> jdList = new List<JieDian>();
for (int i = ; i < items.Length; i++)
{
JieDian jiedian = new JieDian();
jiedian.Id = items[i].DepartId;
jiedian.Name = items[i].DepartName;
jiedian.ParentId = items[i].ParentId;
//递归循环
creatTheTree(items[i].DepartId, jiedian);
jdList.Add(jiedian);
}
jd.children = jdList.ToArray(); //由于对象是引用类型,因为可以改变参数的值
return jd;
} public class JieDian
{
/// <summary>
///
/// </summary>
public string Name { get; set; }
/// <summary>
///
/// </summary>
public Guid Id { get; set; }
/// <summary>
///
/// </summary>
public Guid ParentId { get; set; }
/// <summary>
///
/// </summary>
public JieDian[] children = null;
}
第二种解决方案(key-Value):
#region 尝试不用递归生成树(更简洁高效)
public class ResChapter
{
public string Id { get; set; }
public string Name { get; set; }
public string Pid { get; set; }
public List<ResChapter> Children { get; set; }
} public List<ResChapter> toTree()
{
using (var container = new TRA_EXTContainer())
{
//数据库中的Id和父级Id都是Guid类型,取出的时候转为string类型,而第一级部门PDepartmentId为空,我们用isnull(cast(a.Id as varchar(40)),'')进行处理,如果为空就返回空字符串,否则就把guid转为字符串取出来。
//cast(a.Id as varchar(40)) -----将id转为字符串的操作
string sql = string.Format(@"SELECT a.Name [Name],isnull(cast(a.Id as varchar(40)),'') [Id],isnull(cast(a.PDepartmentId as varchar(40)),'') [Pid]
FROM [HYSYZSCCODB].[dbo].[Department] a
where a.IsValid='true' ");
//这里改成你的数据库表
var data = container.Database.SqlQuery<ResChapter>(sql).ToList(); //这里我直接调用了我库中的类
var chapterlist = data;
var dic = new Dictionary<string, ResChapter>(chapterlist.Count);
foreach (var chapter in chapterlist)
{
dic.Add(chapter.Id, chapter);
}
foreach (var chapter in dic.Values)
{
if (dic.ContainsKey(chapter.Pid))
{
if (dic[chapter.Pid].Children == null)
dic[chapter.Pid].Children = new List<ResChapter>();
dic[chapter.Pid].Children.Add(chapter);
}
}
var dateTree = dic.Values.Where(t => string.IsNullOrEmpty(t.Pid)).ToList();
return dateTree;
}
}
#endregion
获取上属父级部门:
using (var context = new YZS_TRAEntities())
{
var Office = context.事务所主任.Where(f => f.事务所主任ID == officeId).FirstOrDefault();
if (Office == null)
{
result.ErrorCode = ;
result.IsSuccess = false;
result.Msg = "未找到当前登陆人";
return result;
}
UpdateMeetStatus(container);
string sql = string.Format(@"SELECT a.[Name] [EmployeeName],a.Mobile [EmployeePhone],b.Name [DepartName],b.Id [DepartId],b.PDepartmentId [ParentId]
FROM [HYSYZSCCODB].[dbo].[Employee] a
inner join [HYSYZSCCODB].[dbo].[Department] b on b.EmployeeId = a.Id
where b.IsValid='true' and a.Mobile =" + "'" + Office.手机.Trim() + "'");
var entity = container.Database.SqlQuery<OfficeDTO>(sql).FirstOrDefault(); //当前事务所主任的部门
if (entity.ParentId.HasValue)
{
var data = GetParentDeparts(entity.ParentId.Value, list); //获取上级所有部门
data.Add(entity); //再把自身加上
ids = data.Select(f => f.DepartId).ToList();
}
ids.Add(entity.DepartId);
} #region 递归获取父级部门
public List<OfficeDTO> GetParentDeparts(Guid parentId, List<OfficeDTO> list)
{
using (var container = new TRA_EXTContainer())
{ //根据父节点获取选项集合
string sql = string.Format(@"SELECT a.Name [DepartName],a.Id [DepartId],a.PDepartmentId [ParentId]
FROM [HYSYZSCCODB].[dbo].[Department] a
where a.IsValid='true' and a.Id = " + "'" + parentId + "'");
//这里改成你的数据库表
var entity = container.Database.SqlQuery<OfficeDTO>(sql).FirstOrDefault();
if (entity != null)
{
list.Add(entity);
if (entity.ParentId.HasValue)
{
GetParentDeparts(entity.ParentId.Value, list);
}
}
}
return list; }
#endregion
c#所有部门及其下所部门生成树形图(递归算法获取或键值对方式获取)的更多相关文章
- c#字典怎么获取第一个键值 List<对象>获取重复项,转成Dictionary<key,List<对象>>
c#字典怎么获取第一个键值 Dictionary<string, int> dictionary = new Dictionary<string, int>(); dictio ...
- location将地址栏参数拆分成键值对的对象
window.location可获取地址栏的一系列信息,并且每个浏览器都支持该属性,非常方便.而获取到的问号后面的参数可以进行加工转变成我们所想要的键值对. location的属性: 属性名 例子 说 ...
- 键值集合List转换成datatable
/// <summary> /// 键值集合List转换成datatable /// </summary> /// <param name="data" ...
- js中对象转化成字符串、数字或布尔值的转化规则
js中对象可以转化成 字符串.数字.布尔值 一.对象转化成字符串: 规则: 1.如果对象有toString方法,则调用该方法,并返回相应的结果:(代码通常会执行到这,因为在所有对象中都有toStrin ...
- jquery不能是使用普通的for循环 因为普通的for循环通过下表获取对象 如果通过下表获取对象的话 会转成dom对象
jquery不能是使用普通的for循环 因为普通的for循环通过下表获取对象 如果通过下表获取对象的话 会转成dom对象
- java 把json对象中转成map键值对
相关:Json对象与Json字符串的转化.JSON字符串与Java对象的转换 本文的目的是把json串转成map键值对存储,而且只存储叶节点的数据 比如json数据如下: {responseHeade ...
- .Net将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),并使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA
前言: 前段时间因为项目进度比较繁重所以一直都没有时间更新博客,内心深深的负重感,没有履行年初立下的flag.不过这个月会把上个月没有完成的任务补上来,咱们可不是喜欢拖欠任务的攻城狮.哈哈,废话不多说 ...
- php将一个字符串转变成键值对数组的效率问题
有这样一种需求,将形式为"TranAbbr=IPER|AcqSsn=000000073601|MercDtTm=20090615144037"的字符串转换成如下格式的数组: Arr ...
- 将bean转换成键值列表
日常开发中在进行接口对接的数据传输时,有一种场景是将bean转成jsonString,这里可以将bean转换成Map再转成jsonString. 工具类如下: public static String ...
随机推荐
- Spring 声明事务中transactionAttributes属性 + - Exception 实现逻辑
下面是一段典型的Spring 声明事务的配置: <bean id=“baseTxProxy” lazy-init=“true”class=“org.springframework.transac ...
- SVN 分支主干的相互合并
1.主干合并到分支 1在本地trunk中先update一下,有冲突的解决冲突,保证trunk和repository已经完全同步, 2.在/branches /MyProject上右键,依次选择”Tor ...
- epel安装第三方扩展源后,运行yum报错的解决方案
yum安装报错:Cannot retrieve metalink for repository: epel. Please verify its path and try again 解决方法: 一句 ...
- AWS EC2实例Ubuntu系统设置root用户密码并使用root/ubuntu用户登录
参考链接:http://www.wangchao.info/1137.html 注意:链接中写的简化了,其中重启服务的命令似乎不太适用,可能是不通用,我下面描述的方式亲测可行,如有其他疑问请留言: ...
- 解决Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name) 中文显示乱码
如果file.Name为中文则乱码.解决办法是方法1:response.setHeader("Content-Disposition", "attachment; fil ...
- Semaphore 与ThreadPoolExecutor 的使用
1. Semaphore 信号量 (阻塞) 优点:可以控制线程的数量,不会超出线程范围 缺点:当线程死锁时,永远没法释放,导致一直阻塞 在java中,提供了信号量Semaphore的支持. Sema ...
- 深入学习使用ocr算法识别图片中文字的方法
公司有个需求,简单点说需要从一张图片中识别出中文,通过python来实现,当然其他程序也行,只要能实现,而小编主要学习python,所以就提了python.一个小白在网上遨游了一天,终于找到一丝丝思绪 ...
- 前端迷思与React.js
前端迷思与React.js 前端技术这几年蓬勃发展, 这是当时某几个项目需要做前端技术选型时, 相关资料整理, 部分评论引用自社区. 开始吧: 目前, Web 开发技术框架选型为两种的占 80% .这 ...
- Linux中配置别名
Linux中修改配置别名 ####用到的命令: alias是用来查看系统中有什么别名 source 让配置生效 临时取消别名的方法 unalias 临时取消别名 \cp /mnt/test.txt / ...
- Hybris CronJob.
一.概念 CronJobs提供了在特定的时间或者间隔内处理业务逻辑的方法.一般创建一个Cronjob有两种方式,第一种是定义Java类,由Hybris生成脚本并加入数据库.第二种是直接编写gr ...