繁体   English   中英

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

[英]Complex orderby question (entity framework)

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

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

但我不知道如何让秩序以我想要的方式出现。 我需要它以层级显示。 所以,它看起来像:Big Boss- Boss- underling-underling- Boss- underling- Boss- Boss- Big Boss-

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

这似乎是使用任何特定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中实现这一点,但这只能意味着我不够聪明,而不是只是不可能。

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

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;
}

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

我认为,不应该使用LINQ的一切:)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM