我正在使用oracleDB,我有如下视图,其中包含员工和他的经理。
empNo
FirstName
LastName
Manager
我需要挑选一个人和他的所有员工。IE
Person1 is Manager
-- Person1_1
----Person1_1_1
----Person1_1_2
-- Person1_1
当我使用Person1
的用户登录时,我需要获得上面所有的人。
这是我的LINQ,但太慢了。。获取数据的有效方法是什么?
List<decimal> OrgPerson2 = new List<decimal>();
public List<decimal> getOrgPerson(decimal empNo)
{
List<decimal> OrgPerson = new List<decimal>();
OrgPerson.AddRange(db.CRM_PERSON_TITLE_V.Where(c => c.MANAGER == empNo).Select(c => (decimal)c.PERSONID).ToList());
var subPerson = db.CRM_PERSON_TITLE_V.ToList();
foreach (var item in OrgPerson)
{
OrgPerson2.Add(item);
var subPerson2 = subPerson.Where(c => c.MANAGER == item).Select(c => (decimal)c.PERSONID).ToList();
if (subPerson2 != null)
{
if (subPerson2.Count > 0)
{
getOrgPerson(item);
}
}
}
return OrgPerson2.Distinct().ToList();
}
决定尝试您的解决方案,因为我怀疑它为我抛出了StackOverflowException。如果不小心,递归方法会非常糟糕。
这是我的堆栈解决方案。代码不言自明。
List<decimal> GetOrgPerson(decimal id)
{
Stack<Person> iter = new Stack<Person>();
List<decimal> result = new List<decimal>();
iter.Push(db.People.FirstOrDefault(p => p.ID == id));
while (iter.Count() > 0)
{
Person current = iter.Pop();
var subordinates = db.People.Where(p => p.ManagerID == current.ID);
foreach (var s in subordinates)
{
if (result.Contains(s.ID))
continue;
iter.Push(s);
result.Add(s.ID);
}
}
return result;
}
在我的测试用例中,People继承了IEnumerable接口。
您的查询只是递归地获取管理器下的所有员工,它可以大大简化:
public IEmunerable<decimal> getOrgPerson(decimal empNo)
{
foreach (var subEmpNo in db.CRM_PERSON_TITLE_V.Where(c => c.MANAGER == empNo).Select(c => (decimal)c.PERSONID))
{
yield return subEmpNo;
foreach (var subSubEmpNo in getOrgPerson(subEmpNo))
yield return subSubEmpNo;
}
}
您不应该需要Distinct()
,因为每个员工只有一个经理。
此外,我认为您不需要List<decimal>
,您可以添加/删除项目。否则,您可能需要类似OrgPerson2 = getOrgPerson(empNo).ToList()
的东西