复杂的顺序问题(实体框架)

时间:2010-06-10 04:31:20

标签: c# asp.net entity-framework sql-order-by

好的,所以我首先要说的是我对这些东西都是新手,并且尽我所能来完成这个项目。我有一个员工对象,其中包含一个主管字段。当有人在我的页面上输入搜索时,数据网格会显示其名称与搜索匹配的员工。但是,我需要它来显示向他们报告的所有员工以及向原始员工的下属报告的第三层员工。我只需要三层。为了使这更容易,员工只有三个等级,所以如果等级= = 3,该员工不负责其他人。我想从我的员工表中检索所有这些员工的最佳方法就像是

from employee in context.employees
where employee.name == search || employee.boss.name == search || 
employee.boss.boss.name == search

但我不知道如何让orderby以我想要的方式出现。我需要它以层级显示。所以,它看起来像: 大老板- 老板- 下属- 下属- 老板- 下属- 老板- 老板- 大老板 -

就像我说的那样,可能有一种更简单的方法可以解决这个问题,如果有的话,我会全力以赴。您可以给予任何建议,我们将非常感激。

3 个答案:

答案 0 :(得分:4)

这似乎是使用任何特定ORM框架解决的一个困难的要求,至少不是一个简单的步骤。可能需要一个多步骤的过程。

可以通过迭代搜索结果并找到他们的孩子(和孩子的孩子)并将层次结构扁平化为单个列表的方法来实现大致相似的东西。这里有一个示例实现,这个实现使用简单的内存列表:

class Employee
{
    public int Id { get; private set; }
    public int? BossId { get; private set; }
    public string Name { get; private set; }

    public Employee(int id, int? bossId, string name)
    {
        Id = id;
        BossId = bossId;
        Name = name;
    }
}

示例数据:

List<Employee> employees = new List<Employee>();
employees.Add(new Employee(1, null, "Tom Smith"));
employees.Add(new Employee(2, null, "Susan Jones"));
employees.Add(new Employee(3, 1, "Sally Davis"));
employees.Add(new Employee(4, 1, "Robert Roberts"));
employees.Add(new Employee(5, 3, "John Smith"));
employees.Add(new Employee(6, 2, "Tonya Little"));
employees.Add(new Employee(7, 3, "Ty Bell"));
employees.Add(new Employee(8, 4, "Helen Andrews"));
employees.Add(new Employee(9, 2, "Matt Huang"));
employees.Add(new Employee(10, 6, "Lisa Wilson"));

流程:

string searchTerm = "Smith";

var searchResults = employees.Where(e => e.Name.Contains(searchTerm));

List<Employee> outputList = new List<Employee>();

Action<IEnumerable<Employee>, List<Employee>> findUnderlings = null;
findUnderlings = (input, list) =>
{
    foreach (Employee employee in input)
    {
        list.Add(employee);
        var underlings = employees.Where(e => e.BossId == employee.Id);
        findUnderlings(underlings, list);
    }
};

findUnderlings(searchResults, outputList);

显示输出:

foreach (Employee employee in outputList)
{
    Console.WriteLine("{0}\t{1}\t{2}", employee.Id, employee.Name, employee.BossId);
}

结果:

1       Tom Smith
3       Sally Davis     1
5       John Smith      3
7       Ty Bell 3
4       Robert Roberts  1
8       Helen Andrews   4
5       John Smith      3

你可以看到它跟随顶级结果,下划线,下属,下一个结果,任何下属等。它适用于任意数量的层。

我不确定如何在Linq中的“order by”或甚至常规SQL中实现这一点,但这只能意味着我不够智能而不是这是不可能的。

答案 1 :(得分:2)

嘿,我想我会发布我最终解决这个问题的方式,以防它可能派上用场其他人。

var list = productQuery.ToList();
var productList = Functions.sortResultsList(list);




public static List<SolutionsModel.Version> 
   sortResultsList(List<SolutionsModel.Version> list)
{
    var productList = new List<SolutionsModel.Version>();

    int total = list.Count();
    int solutions = 0;
    int objects = 0;

    for (int length = 0; length < list.Count(); length++)
    {
        if (list[length].Product.TypeID == 1)
        {
            ++solutions;
        }
        else if (list[length].Product.TypeID == 2)
        {
            ++objects;
        }
    }

    //These nested for-loops create a list that is 
    //correctly ordered to fit correctly into the grid. 
    //Perhaps consider more efficient improvision at a later time.

    //These for loops can't be used if there are not any solutions 
    //in the results
    if (solutions != 0)
    {
        for (int x = 0; x < list.Count; x++)
        {
            if (list[x].Product.TypeID == 1)
            {
                productList.Add(list[x]);
                for (int y = 0; y < list.Count; y++)
                {
                    if (list[y].Product.TypeID != 1)
                    {
                        if (list[y].Product.Product2.ID == list[x].Product.ID && list[y].VersionNumber == list[x].VersionNumber)
                        {
                            productList.Add(list[y]);
                            for (int j = 0; j < list.Count; j++)
                            {
                                if (list[j].Product.TypeID == 3)
                                {
                                    if (list[j].Product.Product2.ID == list[y].Product.ID && list[j].VersionNumber == list[y].VersionNumber)
                                    {
                                        productList.Add(list[j]);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    //This can't be used if the results do not contain any objects.
    if (objects != 0 && productList.Count != total)
    {
        for (int y = 0; y < list.Count; y++)
        {
            if (list[y].Product.TypeID == 2)
            {
                productList.Add(list[y]);
                for (int j = 0; j < list.Count; j++)
                {
                    if (list[j].Product.TypeID == 3)
                    {
                        if (list[j].Product.Product2.ID == list[y].productID && list[j].VersionNumber == list[y].VersionNumber)
                        {
                            productList.Add(list[j]);
                        }
                    }
                }
            }
        }

    }

    //If the results contain only modules, no sorting is required and the original list can be used.
    if (productList.Count != total)
    {
          return list;
    }

    return productList;
}

答案 2 :(得分:1)

我对LINQ知之甚少。但是,为什么不能使用存储过程来完成,这可以由您的EF模型引用?

我认为,不应该为所有事情使用LINQ:)

编辑:我之所以说使用存储过程是有道理的,是因为EF必须生成SQL查询才能做你想要的事情。你想做什么,可以更好地表达和在SQL中控制。