Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

Troubleshooting
Research
Professional Opinions
Ask a Question
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

troubleshooting Question

Can ExpressionBuilder work with complex data types?

Avatar of dyarosh
dyarosh asked on
.NET ProgrammingC#LINQ Query
8 Comments1 Solution545 ViewsLast Modified:
I am trying to use ExpressionBuilder to build dynamic queries to retrieve data.  I was able to get it to work successfully for a simple example.
        public class Person
        {
            public string Name { get; set; }
            public string Surname { get; set; }
            public int Age { get; set; }
            public string City { get; set; }
            public double Salary { get; set; }
            public bool IsHomeOwner { get; set; }
        }

        public List<Person> PopulatePersonsList()
        {
            List<Person> persons = new List<Person>
            {
                new  Person  { Name = "Flamur" , Surname = "Dauti" ,    Age = 39, 
                               City = "Prishtine" , IsHomeOwner = true ,  Salary = 12000.0 },
                new  Person  { Name = "Blerta" , Surname = "Frasheri" , Age = 25, 
                               City = "Mitrovice" , IsHomeOwner = false , Salary = 9000.0 },
                new  Person  { Name = "Berat" ,  Surname = "Dajti" ,    Age = 45, 
                               City = "Peje" ,      IsHomeOwner = true ,  Salary = 10000.0 },
                new  Person  { Name = "Laura" ,  Surname = "Morina" ,   Age = 23, 
                               City = "Mitrovice" , IsHomeOwner = true ,  Salary = 25000.0 },
                new  Person  { Name = "Olti" ,   Surname = "Kodra" ,    Age = 19, 
                               City = "Prishtine" , IsHomeOwner = false , Salary = 8000.0 },
                new  Person  { Name = "Xhenis" , Surname = "Berisha" ,  Age = 26, 
                               City = "Gjakove" ,   IsHomeOwner = false , Salary = 7000.0 },
                new  Person  { Name = "Fatos" ,  Surname = "Gashi" ,    Age = 32, 
                               City = "Peje" ,      IsHomeOwner = true ,  Salary = 6000.0 },
            };
            return persons;
        }

        [TestMethod]
        public void Returns_Three_Records_When_Name_Equals_Flamur_Or_City_Equals_Peje_And_Age_Equals_39_()
        {
            // Arrange
            List<Person> persons = PopulatePersonsList();
            List<Filter> filter = new List<Filter>()
            {
                new Filter { PropertyName = "Name", Operation = Op.Equals, Value = "Flamur", Conditional = ConOp.Or },
                new Filter { PropertyName = "City", Operation = Op.Equals, Value = "Peje", Conditional = ConOp.And },
                new Filter { PropertyName = "Age", Operation = Op.Equals, Value = 39, Conditional = ConOp.None }
            };

            // Act
            var deleg = ExpressionBuilder.GetExpression<Person>(filter).Compile();
            var filteredCollection = persons.Where(deleg).ToList() as List<Person>;

            // Assert
            Assert.AreEqual(3, filteredCollection.Count, "Record counts do not match");
        }

Now I want to use a class with a complex data type and I am having a problem.  Here is what I have so far:
        public partial class EMP_ALIGNMENT
        {
            public decimal ALIGNMENTID { get; set; }
            public decimal DIVISIONID { get; set; }
            public decimal DEPARTMENTID { get; set; }
            public decimal GROUPID { get; set; }
            public decimal FUNCTIONID { get; set; }
            public Nullable<System.DateTime> LASTUPDATETIMESTAMP { get; set; }
            public string ACTIVESTATUSFLAG { get; set; }
        }
        public partial class EMP_CALLCENTER
        {
            public int CALLCENTERID { get; set; }
            public int EMPLOYEEID { get; set; }
            public Nullable<System.DateTime> PODDATE { get; set; }
            public Nullable<System.DateTime> FLOORDATE { get; set; }
            public Nullable<int> LANGUAGEID { get; set; }
            public Nullable<int> PRIMARYSYSTEMID { get; set; }
            public string DCTM_R_OBJECT_ID { get; set; }
            public Nullable<System.DateTime> LASTUPDATETIMESTAMP { get; set; }

            public virtual EMP_EMPLOYEE EMP_EMPLOYEE { get; set; }
        }
        public partial class EMP_EMPLOYEE
        {
            public EMP_EMPLOYEE()
            {
                this.EMP_IDS = new HashSet<EMP_IDS>();
            }

            public int EMPLOYEEID { get; set; }
            public string NT_ID { get; set; }
            public string FIRSTNAME { get; set; }
            public string LASTNAME { get; set; }
            public string NICKNAME { get; set; }
            public string EMAILADDRESS { get; set; }
            public string COSTCENTER { get; set; }
            public string CJACKNO { get; set; }
            public int TITLEID { get; set; }
            public Nullable<int> MANAGERSUPERVISORID { get; set; }
            public Nullable<int> APPROVALSUPERVISORID { get; set; }
            public int LOCATIONID { get; set; }
            public Nullable<int> SUBLOCATIONID { get; set; }
            public int ALIGNMENTID { get; set; }
            public int STATUSID { get; set; }
            public Nullable<System.DateTime> HIREDATE { get; set; }
            public Nullable<System.DateTime> PROMOTIONDATE { get; set; }
            public Nullable<int> PROMOTIONREASONID { get; set; }
            public Nullable<System.DateTime> TRANSFERDATE { get; set; }
            public Nullable<int> TRANSFERREASONID { get; set; }
            public Nullable<System.DateTime> TERMINATIONDATE { get; set; }
            public Nullable<int> TERMINATIONREASONID { get; set; }
            public Nullable<System.DateTime> LOASTARTDATE { get; set; }
            public Nullable<System.DateTime> LOAENDDATE { get; set; }
            public string TIMEZONE { get; set; }
            public Nullable<System.DateTime> LASTUPDATETIMESTAMP { get; set; }
            public string SUFFIX { get; set; }

            public virtual EMP_ALIGNMENT EMP_ALIGNMENT { get; set; }
            public virtual EMP_CALLCENTER EMP_CALLCENTER { get; set; }
            public virtual EMP_EMPLOYEEALIGNMENT EMP_EMPLOYEEALIGNMENT { get; set; }
            public virtual ICollection<EMP_IDS> EMP_IDS { get; set; }
        }
        public partial class EMP_EMPLOYEEALIGNMENT
        {
            public int EMPLOYEEID { get; set; }
            public int SUPERVISORID { get; set; }
            public int MANAGERID { get; set; }
            public int DIRECTORID { get; set; }
            public Nullable<System.DateTime> LASTUPDATETIMESTAMP { get; set; }
        }
        public partial class EMP_IDS
        {
            public int IDSID { get; set; }
            public int EMPLOYEEID { get; set; }
            public int IDTYPEID { get; set; }
            public string IDVALUE { get; set; }
            public Nullable<System.DateTime> LASTUPDATETIMESTAMP { get; set; }

            public virtual EMP_EMPLOYEE EMP_EMPLOYEE { get; set; }
        }

        public List<EMP_EMPLOYEE> PopulateEmployeeProfile()
        {
            List<EMP_EMPLOYEE> employee = new List<EMP_EMPLOYEE>
            {
                new EMP_EMPLOYEE { 
                    EMPLOYEEID = 5810, NT_ID = @"AIGM_WILM\JSMITH", FIRSTNAME = "JOHN", LASTNAME = "SMITH", NICKNAME = "JONNY", 
                    EMAILADDRESS = "JOHN.SMITH@21ST.COM", COSTCENTER = "21177A1010", CJACKNO = "14627", TITLEID = 38, MANAGERSUPERVISORID = 0, 
                    APPROVALSUPERVISORID = 231, LOCATIONID = 3, SUBLOCATIONID = 0, ALIGNMENTID = 727, STATUSID = 1, 
                    HIREDATE = Convert.ToDateTime("06/04/2012"), PROMOTIONDATE = Convert.ToDateTime("05/01/2014"), PROMOTIONREASONID = 23, 
                    TRANSFERDATE = Convert.ToDateTime("07/07/2014"), TRANSFERREASONID = 196, TERMINATIONDATE = null, TERMINATIONREASONID = 0, 
                    LOAENDDATE = null, LOASTARTDATE = null, SUFFIX = null, TIMEZONE = "EDT", 
                    EMP_ALIGNMENT = new EMP_ALIGNMENT { ALIGNMENTID = 727, DIVISIONID = 4, DEPARTMENTID = 63, GROUPID = 261, FUNCTIONID = 401 },
                    EMP_CALLCENTER = new EMP_CALLCENTER { CALLCENTERID = 1, EMPLOYEEID = 5810, PODDATE = Convert.ToDateTime("06/04/2012"),
                                                          FLOORDATE = Convert.ToDateTime("09/04/2012"), LANGUAGEID = 1, PRIMARYSYSTEMID = 1,
                                                          DCTM_R_OBJECT_ID = null 
                    },
                    EMP_EMPLOYEEALIGNMENT = new EMP_EMPLOYEEALIGNMENT { EMPLOYEEID = 5810, SUPERVISORID = 231, MANAGERID = 5201, DIRECTORID = 399 },
                    EMP_IDS = new List<EMP_IDS> {
                                                    new EMP_IDS { IDSID = 22270, EMPLOYEEID = 5810, IDTYPEID = 2, IDVALUE = "0162161" },
                                                    new EMP_IDS { IDSID = 22272, EMPLOYEEID = 5810, IDTYPEID = 4, IDVALUE = "70162161" },
                                                    new EMP_IDS { IDSID = 22273, EMPLOYEEID = 5810, IDTYPEID = 8, IDVALUE = "32381" },
                                                    new EMP_IDS { IDSID = 25001, EMPLOYEEID = 5810, IDTYPEID = 5, IDVALUE = "23" },
                                                    new EMP_IDS { IDSID = 24867, EMPLOYEEID = 5810, IDTYPEID = 69, IDVALUE = "Y" }
                                                }
               }
            };
            return employee;
        }

        [TestMethod]
        public void Returns_One_Record_When_Empoyee_Supervisorid_Is_Specified()
        {
            // Arrange
            List<EMP_EMPLOYEE> emp = PopulateEmployeeProfile();

            List<Filter> filter = new List<Filter>()
            {
                new Filter { PropertyName = "EMP_EMPLOYEEALIGNMENT.SUPERVISORID", Operation = Op.Equals, Value = 231, Conditional = ConOp.None },
            };

            // Act
            var deleg = ExpressionBuilder.GetExpression<EMP_EMPLOYEE>(filter).Compile();
            var filteredCollection = emp.Where(deleg).ToList() as List<EMP_EMPLOYEE>;
 
            // Assert
            Assert.AreEqual(0, filteredCollection.Count, "Record counts do not match");
        }

When I run the test I get the following error:
Test method ExpressionBuilderClassTests.ExpressionBuilderTests.Returns_One_Record_When_Empoyee_Supervisorid_Is_Specified threw exception: 
System.ArgumentException: Instance property 'EMP_EMPLOYEEALIGNMENT.SUPERVISORID' is not defined for type 'ExpressionBuilderClassTests.ExpressionBuilderTests+EMP_EMPLOYEE'

Here is the line of code that is throwing the error:  
private static Expression GetExpression<T>(ParameterExpression param, Filter filter)
        {
            MemberExpression member = Expression.Property(param, filter.PropertyName);

If I set PropertyName = "EmployeeID" it works.  I appreciate any help in trying to figure this out.