Search code examples
c#linqclass-design

Only get filtered elements from class properties


Below is how the code looks like. Note that all of the EmployeeSomethingA, EmployeeSomethingB, EmployeeSomethingC class have a common EmployeeID property.

class EmployeesData
    {
        public List<EmployeeSomethingA> EmployeeSomethingAs { get; set; }
        public List<EmployeeSomethingB> EmployeeSomethingBs { get; set; }
        public List<EmployeeSomethingC> EmployeeSomethingCs { get; set; }
    }

    class EmployeeSomethingA
    {
        public int EmployeeID { get; set; }
        public string SomethingA { get; set; }
    }

    class EmployeeSomethingB
    {
        public int EmployeeID { get; set; }
        public string SomethingB { get; set; }
        public float SomethingBA { get; set; }
    }
    class EmployeeSomethingC
    {
        public int EmployeeID { get; set; }
        public string SomethingC { get; set; }
        public Guid SomethingCA { get; set; }
        public double SomethingCB { get; set; }
    }

I want add ability on EmployeesData class so that I can retrieve filtered from EmployeeSomethingAs, EmployeeSomethingBs and EmployeeSomethingCs for a particular EmployeeID. I am not sure I can use linq where in this case but I would like is something as follows.

EmployeeDataInstance.Where ( x => x.EmployeeID > 2);

This should return only an EmployeeData instance where EmployeeSomethingAs, EmployeeSomethingBs and EmployeeSomethingCs will contains data with EmployeeID > 2. I don't know if implementing IEnumerable can get me this ability. Any idea how this could be accomplished?


Solution

  • You can try something like that;

    Create Employee class that contains shared property EmployeeID and other classes are derived from it.

    class Employee
    {
        public int EmployeeID { get; set; }
    }
    class EmployeeSomethingA : Employee
    {
        public string SomethingA { get; set; }
    }
    
    class EmployeeSomethingB : Employee
    {
        public string SomethingB { get; set; }
    }
    class EmployeeSomethingC : Employee
    {
        public string SomethingC { get; set; }
    }
    

    And create Where method to perform where clause for EmployeesData class;

    class EmployeesData
    {
        public List<EmployeeSomethingA> EmployeeSomethingAs { get; set; }
        public List<EmployeeSomethingB> EmployeeSomethingBs { get; set; }
        public List<EmployeeSomethingC> EmployeeSomethingCs { get; set; }
    
        public void Where(Func<Employee, bool> predicate)
        {
            EmployeeSomethingAs = EmployeeSomethingAs.Where((Func<EmployeeSomethingA, bool>)predicate).ToList();
            EmployeeSomethingBs = EmployeeSomethingBs.Where((Func<EmployeeSomethingB, bool>)predicate).ToList();
            EmployeeSomethingCs = EmployeeSomethingCs.Where((Func<EmployeeSomethingC, bool>)predicate).ToList();
        }
    }
    

    Usage;

    employeesData.Where(x => x.EmployeeID == 1);
    

    EDIT

    If you want to filter the list properties as new EmployeesData instance you can modify Where method like this;

    public EmployeesData Where(Func<Employee, bool> predicate)
    {
        return new EmployeesData
        {
            EmployeeSomethingAs = EmployeeSomethingAs.Where((Func<EmployeeSomethingA, bool>)predicate).ToList(),
            EmployeeSomethingBs = EmployeeSomethingBs.Where((Func<EmployeeSomethingB, bool>)predicate).ToList(),
            EmployeeSomethingCs = EmployeeSomethingCs.Where((Func<EmployeeSomethingC, bool>)predicate).ToList()
        };
    }
    
    var newEmployeesData = employeesData.Where(x => x.EmployeeID == 1);