为循环查询编写lingq的最佳方法

时间:2014-04-14 18:13:53

标签: asp.net asp.net-mvc linq

我正在使用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();
}

2 个答案:

答案 0 :(得分:0)

决定试用你的解决方案,因为我怀疑它为我扔了一个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接口。

答案 1 :(得分:0)

您的查询只是递归地让管理员下的所有员工,它可以大大简化:

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()

之类的内容