查找自定义类型列表的最大计数

时间:2013-06-18 22:34:40

标签: c# asp.net linq

我有一个模拟应用程序,其中包含一个继承链 Employee,Manager,President等。

Employee类看起来像

class Employee
    {
        public int EmployeeId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }

        public Employee() 
        { 
        }
    }

,Manager类看起来像

 class Manager : Employee
    {

        private List<Employee> employeesManaged = new List<Employee>();
        public List<Employee> EmployeesManaged
        {
            get { return employeesManaged; }
            set { employeesManaged = value; }
        }
    }

我想编写一个方法来查找管理大多数员工的经理(其EmployeesManaged.Count属性是最大的)。我目前有两个问题。

  1. 正如您在下面的代码中看到的那样,我必须手动将每个Manager添加到List变量中。这不是一个长期的解决方案。什么是解决这个问题的有效,简洁的方式?

  2. 我的Linq语法不正确。

  3. 我认为第一个问题是最紧迫的。如果有1000个Employee对象,我将如何规避将每个对象添加到列表中?

     public static Manager  GetBestManager(List<Manager> managerList)
            {
                Manager m = managerList.Select(x => x.EmployeesManaged).Max();
    
            }
    

    我的主要方法

    Employee e = new Employee();
                e.EmployeeId = 101;
                e.FirstName = "Tom";
                e.LastName = "Jones";
                e.HireDate = DateTime.Now.Subtract(TimeSpan.FromDays(40));
    
                Employee e2 = new Employee();
                e2.EmployeeId = 102;
    
    
                Employee e3 = new Employee();
                e3.EmployeeId = 103;
    
    
                Manager m = new Manager();
                m.EmployeeId = 201;
                m.EmployeesManaged.Add(e);
                m.EmployeesManaged.Add(e2);
    
                Manager m2 = new Manager();
                m2.EmployeesManaged.Add(e3);
    
                List<Manager> mList = new List<Manager>();
                mList.Add(m);
                mList.Add(m2);
                Manager.GetBestManager(mList);
    

    使用当前语法我收到错误'无法将类型Employee隐式转换为Manager

4 个答案:

答案 0 :(得分:8)

1)这取决于数据的来源。内存集合中的数据库,磁盘文件。 List或其他结构通常由来源确定。

2)您的LINQ获得最大数量,而不是具有最高计数的Manager。尝试:

public static Manager GetBestManager(List<Manager> managerList)
{
    Manager m = managerList.OrderByDescending(x => x.EmployeesManaged.Count).First();
    return m;
}

答案 1 :(得分:4)

快速且可能更脏的解决方案:

return managerList
       .OrderByDescending(x => x.EmployeesManaged.Count)
       .FirstOrDefault();

答案 2 :(得分:3)

在这篇文章中看到我的回答: How can I get LINQ to return the object which has the max value for a given property?

您可以使用System.Linq中的Aggregate函数

聚合速度更快,因为它只是在集合中运行一次并且随着时间的推移而最大化。 OrderBy基本上必须进行更冒险的冒泡排序。

答案 3 :(得分:1)

我认为这可能是你想要的:

public static Manager GetBestManager(this IList<Manager> managerList) {
    Func<Manager, int> getCount=x => x.EmployeesManaged.Count;
    return managerList.First(x => getCount(x)==managerList.Max(getCount));
}

如果有多个经理拥有相同数量的员工,则返回第一个。不使用FirstOrDefault的原因是因为从列表中获取了最大值,我们总能找到一个匹配最大值的管理器,除了集合为空。

那么,为什么使用FirstOrDefault返回null而不是抛出异常让调用者知道谁传递了空列表呢?