none
Linq expresion to remove duplicate code RRS feed

  • Question

  • I am writing queries in my code which is Linq to Sql. I am not very familiar with expressions, I want to write an expression which checks if in a IEnumerable any of the item satisfies the condition

    public class TestClass1
    {
        // can be any number of properties, with diff names and types
        public string TestProperty1 { get; set; }
        public string TestProperty2 { get; set; }
        public List<TestClass1ExtraFieldValue> TestClass1ExtraFieldValueList { get; set; }
    }
    
    public class TestClass1ExtraFieldValue
    {
        public TestClass1ExtraField TestClass1ExtraField { get; set; }
    
        // property names below are same in all classes which name ends with ExtraFieldValue
        public int IntValue { get; set; }
        public bool BoolValue { get; set; }
        public DateTime DateTimeValue { get; set; }
        public string StringValue { get; set; }
    }
    
    public class TestClass1ExtraField
    {
        // property names are same in all classes which name ends with ExtraField
        public string Property1 { get; set; }
        public string Property2 { get; set; }
    }
    
    public class TestClass2
    {
        // can be any number of properties, with diff names and types
        public string TestProperty1 { get; set; }
        public string TestProperty2 { get; set; }
        public List<TestClass2ExtraFieldValue> TestClass2ExtraFieldValueList { get; set; }
    }
    
    public class TestClass2ExtraFieldValue
    {
        public TestClass2ExtraField TestClass2ExtraField { get; set; }
    
        // property names below are same in all classes which name ends with ExtraFieldValue
        public int IntValue { get; set; }
        public bool BoolValue { get; set; }
        public DateTime DateTimeValue { get; set; }
        public string StringValue { get; set; }
    }
    
    public class TestClass2ExtraField
    {
        // property names are same in all classes  which name ends with ExtraField
        public string Property1 { get; set; }
        public string Property2 { get; set; }
    }
    
    // NOT a DB class
    public class ExtraFieldClass
    {
        public string Property1 { get; set; }
        public string Property2 { get; set; }
        public int IntValue { get; set; }
        public bool BoolValue { get; set; }
        public DateTime DateTimeValue { get; set; }
        public string StringValue { get; set; }
    }

    And my Query class are like below,

    public class TestClass1Query
    {
        public string TestValue1;
        public string TestValue2;
    
        List<ExtraFieldClass> ExtraFieldsList { get; set; }
    
        public IQueryable GetQuery()
        {
            var query = GetTestClass1Values().Where(c=> c.TestProperty1==TestValue1 && c.TestProperty2 == TestValue2);
            // some condition checks
            foreach (var extraField in ExtraFieldsList)
            {
                switch (extraField.Type)
                {
                        case FieldType.Boolean:
                        {
                            var boolValue = Convert.ToBoolean(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass1ExtraFieldValueList.Any(t => t.TestClass1ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass1ExtraField.Property2 == extraField.Property2
                                                                                          && t.BoolValue == boolValue));
                            break;
                        }
    
                        case FieldType.DateTime:
                        {
                            var dateTimeValue = Convert.ToDateTime(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass1ExtraFieldValueList.Any(t => t.TestClass1ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass1ExtraField.Property2 == extraField.Property2
                                                                                          && t.DateTimeValue == dateTimeValue));
                            break;
                        }
    
                        case FieldType.Text:
                        {
                            var stringValue = Convert.ToString(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass1ExtraFieldValueList.Any(t => t.TestClass1ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass1ExtraField.Property2 == extraField.Property2
                                                                                          && t.StringValue == stringValue));
                            break;
                        }
    
                        case FieldType.Integer:
                        {
                            var integerValue = Convert.ToInt32(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass1ExtraFieldValueList.Any(t => t.TestClass1ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass1ExtraField.Property2 == extraField.Property2
                                                                                          && t.IntValue == integerValue));
                            break;
                        }
                }
            }
            return query;
        }
    
        private IQueryable<TestClass1> GetTestClass1Values()
        {
            return null;
        }
    }
    
    public class TestClass2Query
    {
        public string TestValue1;
        public string TestValue2;
    
        List<ExtraFieldClass> ExtraFieldsList { get; set; }
    
        public IQueryable GetQuery()
        {
            var query = GetTestClass2Values().Where(c => c.TestProperty1 == TestValue1 && c.TestProperty2 == TestValue2);
            // some condition checks
            foreach (var extraField in ExtraFieldsList)
            {
                switch (extraField.Type)
                {
                    case FieldType.Boolean:
                        {
                            var boolValue = Convert.ToBoolean(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass2ExtraFieldValueList.Any(t => t.TestClass2ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass2ExtraField.Property2 == extraField.Property2
                                                                                          && t.BoolValue == boolValue));
                            break;
                        }
    
                    case FieldType.DateTime:
                        {
                            var dateTimeValue = Convert.ToDateTime(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass2ExtraFieldValueList.Any(t => t.TestClass2ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass2ExtraField.Property2 == extraField.Property2
                                                                                          && t.DateTimeValue == dateTimeValue));
                            break;
                        }
    
                    case FieldType.Text:
                        {
                            var stringValue = Convert.ToString(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass2ExtraFieldValueList.Any(t => t.TestClass2ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass2ExtraField.Property2 == extraField.Property2
                                                                                          && t.StringValue == stringValue));
                            break;
                        }
    
                    case FieldType.Integer:
                        {
                            var integerValue = Convert.ToInt32(extraField.Fieldvalue);
                            query = query.Where(c => c.TestClass2ExtraFieldValueList.Any(t => t.TestClass2ExtraField.Property1 == extraField.Property1
                                                                                          && t.TestClass2ExtraField.Property2 == extraField.Property2
                                                                                          && t.IntValue == integerValue));
                            break;
                        }
                }
            }
            return query;
        }
    
        private IQueryable<TestClass2> GetTestClass2Values()
        {
            return null;
        }
    }    

    Now if you see my Query classes, each has its own condition checks and for extra fields the logic is same only the names change. And I have 20 class similar to this. And I don't want to have the same repeated code every where. I searched and came to know that we can use linq-expressions to have a generic code for this.

    I have no knowledge on writing expressions, Any suggestions or ways to achieve this?


    Please mark the post as answer if it is helpfull to you - Hiran Repakula

    Friday, July 3, 2015 2:55 PM

All replies

  • My first question is exactly what are you attempting to accomplish.  If you are attempting to get rid of duplicates (not sure what you mean by code), you should implement the IComparable interface (https://msdn.microsoft.com/en-us/library/system.icomparable%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396).  


    Lloyd Sheen

    Sunday, July 5, 2015 10:49 PM
  • Hello Hiran.Repakula,

    >> And I have 20 class similar to this. And I don't want to have the same repeated code every where

    As you mentions, each has its own condition checks and for extra fields the logic is same only the names change, so why not abstract foreach statement to a generic method so that you just need to apply the correspond type so that you can reuse it without writing the repeated code everywhere.

    I also noticed that for your provided these classes, I noticed that TestClass1ExtraFieldValue is completely the same with TestClass2ExtraFieldValue, and the same for TestClass1ExtraField and TestClass2ExtraField, so why not just write one class so that in your foreach statement, the problem that the name is different would go.

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, July 6, 2015 3:03 AM
    Moderator
  • Hi,

    As I mentioned I am writing Linq to SQL, where C# Functions will not work. The classes which I mentioned represents my Tables in SQL, so I cannot use a generic class for all tables.


    Please mark the post as answer if it is helpfull to you - Hiran Repakula

    Monday, July 6, 2015 7:55 AM
  • Hello Hiran,

    Check this link below, which could be helpful for you to construct the lambda expression:

    http://www.codeproject.com/Articles/33769/Basics-of-LINQ-Lamda-Expressions

    Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, July 8, 2015 2:06 AM
    Moderator