Wednesday, December 26, 2012

Linq GroupBy with Aggregate functions

 List<Employee> empList = new List<Employee>();  
       empList.AddRange(new Employee[]   
       {   
         new Employee {EmpId =1, DeptId=1, Position="Director", Salary=100 },  
         new Employee {EmpId =2, DeptId=1, Position="Director", Salary = 120},  
         new Employee {EmpId =3, DeptId=1, Position="Software Engineer", Salary=50 },  
         new Employee {EmpId =4, DeptId=2, Position="Director", Salary=90 },  
         new Employee {EmpId =5, DeptId=2, Position="Director", Salary=100 },  
         new Employee {EmpId =6, DeptId=3, Position="HR Assistant", Salary=40 },  
         new Employee {EmpId =7, DeptId=3, Position="HR Manager", Salary=70},  
         new Employee {EmpId =8, DeptId=4, Position="IT Manager", Salary=85 },  
         new Employee {EmpId =8, DeptId=4, Position="IT Assistant", Salary=40 }  
       });  
   
       /*  
        * The highest salary from the each dept per position  
       */  
       empList.GroupBy(_ => new { _.DeptId, _.Position })  
         .Select(_ => new  
         {  
           MaximumSalary = _.Max(deptPositionGroup => deptPositionGroup.Salary),  
           DepartmentId = _.Key.DeptId,  
           Position = _.Key.Position  
         }).ToList()  
         .ForEach(selectedRecords =>  
         {  
           Console.WriteLine("{0} {1} {2}", selectedRecords.DepartmentId, selectedRecords.Position, selectedRecords.MaximumSalary);  
         });  
   
       /*Average salary from each dept per position */  
   
       Console.WriteLine();  
       Console.WriteLine();  
       Console.WriteLine();  
       empList.GroupBy(_ => new { _.DeptId, _.Position })  
               .Select(_ => new  
               {  
                 AverageSalary = _.Average(deptPositionGroup => deptPositionGroup.Salary),  
                 DepartmentId = _.Key.DeptId,  
                 Position = _.Key.Position  
               }).ToList()  
               .ForEach(selectedRecords =>  
               {  
                 Console.WriteLine("{0} {1} {2}", selectedRecords.DepartmentId, selectedRecords.Position, selectedRecords.AverageSalary);  
               });  
       Console.WriteLine();  
       Console.WriteLine();  
       Console.WriteLine();  
       /*Average salary from each dept */  
       empList.GroupBy(_ => _.DeptId)  
               .Select(_ => new  
               {  
                 AverageSalary = _.Average(deptPositionGroup => deptPositionGroup.Salary),  
                 DepartmentId = _.Key,  
               }).ToList()  
               .ForEach(selectedRecords =>  
               {  
                 Console.WriteLine("{0} {1}", selectedRecords.DepartmentId, selectedRecords.AverageSalary);  
               });  

Tuesday, December 18, 2012

Convert Dictionary into Strongly Typed Class


There are few things you have to consider before conversion of dictionary into strongly typed class object.

1 - To detect in which class you want to convert into dictionary. For this purpose you need generic (Template) where you will specify in which class you want to convert.

2 - Get the properties of the strongly typed class using reflection.

3 - Create the object of the Generic . and get the reference of it.

4 - Iterate the properties of object and search the dictionary contains that field or column, if its find and writeable then set the value using reflection but cast the values into the strongly typed of a column too.

Here's the demo.

   class Emp {
      public string Name { get; set; }
      public string TechnologyExpert { get; set; }
      public int Salary { get; set; }
      public override string ToString(){
         return Name + "-----" + TechnologyExpert + "-----" + Salary;
      }
   }
   class Cust{
      public string Name { get; set; }
      public string Company { get; set; }
      public override string ToString(){
         return Name + "------" + Company;
      }
   }

/// Please use angle bracket here too.
   class ConvertIntoStronglyTyped  where T: new() {
      public static T ConvertMe(Dictionary objectDict)
      {
         var properties = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
       
         Object obj = new T();
       
         foreach (var property in properties)
            if (property.CanWrite && objectDict.ContainsKey(property.Name))            
               property.SetValue(obj, Cast(property.PropertyType.FullName, objectDict[property.Name]), null);                  

         return (T)obj;
      }

      private static object Cast(string propertyTypeName, object value) {
         string strFullName = typeof(string).FullName;
         string intFullName = typeof(int).FullName;
         string floatFullName = typeof(float).FullName;

         if (strFullName == propertyTypeName)   return value.ToString();
         if (intFullName == propertyTypeName)   return int.Parse(value.ToString());
         if (floatFullName == propertyTypeName) return int.Parse(value.ToString());
       
         return value;
      }
   }

Execute the code.

class Program
   {
      static void Main(string[] args)
      {
         Dictionary consolidatedValues = new Dictionary();
       
         consolidatedValues.Add("Name", "Sohail");
         consolidatedValues.Add("TechnologyExpert", "C#");
         consolidatedValues.Add("Salary", "200");
         consolidatedValues.Add("Company", "ABC .Com");

// I noticed the less than greater than bracket is not visible, use simple the angle brackets.
         Emp emp = ConvertIntoStronglyTyped&ltEmp&gt.ConvertMe(consolidatedValues);

         Cust cust = ConvertIntoStronglyTyped.ConvertMe(consolidatedValues);
         Console.WriteLine(emp);
         Console.WriteLine(cust);
      }
   }

Please let me know incase you are facing issue and have more questions regarding the reflections or generics.




Wednesday, June 8, 2011

demo project convert Datatable to LIST


You can find the project here

Explanation of both conversions from DataTable to List using Reflection and LINQ are already explained in the previous posts.

Friday, May 20, 2011

Convert datatable into list using reflection

Using reflection we can convert the datatable into strongly typed collection. I'll prefer list as a collection.

Let's suppose I have a class of Emp and I have put two fields in it. 
class Emp{ string Id {get; set;} string Name{get; set;}}
Now, to convert datatable into any class, Ofcourse we'll have to use Generic template that will find the type of the class. 
We are creating a class that will convert Datatable into strongly typed list. 

This is the declaration of a class where we will refer any business class as a 'T' and that 'T' type should have a constructor with no arguments. We are ensuring in the where. 
public class DatatableToListMapper : where T : new()
We will create a method ConvertDataTableIntoList where Datatable will be passed as an argument and this method will return List of type T.
Here's the signature of the method.
List ConvertDataTableIntoList(DataTable dt)
// create list of type T.
List objT = new List();
Now we will fetch every row from the DataTable.
foreach(DataRow dr in dt.Rows)
Now we will get the properties of the T class using the method typeof(T).GetProperties() and will retrieve every property using loop. Create an object of type T.

e.g. 
T obj = new T();
foreach(var property in typeof(T).GetProperties()){
property.SetValue(obj, dr[property.Name], null); /// Setting the property value in the object obj.
}
//Add this object in a 
objT.Add(obj);

At last return the object of list after conversion. I'll share the code in the next post where the mapping can be user defined using a Dictionary collection.


return objT;


Thursday, May 19, 2011

Convert Datatable into collection using LINQ

We can create the anonymous type from the data table but If we are interested to convert data table into strongly typed collection like List of Emp type from the datatable. Below is the code snippet.

    public class Emp
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

                DataTable dt = new DataTable();
                dt.Columns.Add("EmpId");
                dt.Columns.Add("EmpName");
                dt.Rows.Add("1", "Sohail");
                dt.Rows.Add("2", "Yasir");
                dt.Rows.Add("3", "Shahid");
Convert data type into AsEnumerable and then select the rows from the table and put one by one field in the emp object.
             List emp = new List();
             var result = from p in dt.AsEnumerable()
             select new Emp
             {
                     Id = int.Parse(p[0].ToString()),
                     Name = p[1].ToString()
             };

          After all, convert the result into List of Emp type.
           emp = result.ToList();       
           foreach (var row in emp)
           Console.WriteLine("{0}, {1}", row.Id, row.Name);

Friday, April 29, 2011

Defaulting Dimension in AX

What is defaulting dimension means?

Defaulting dimension means to provide the default values to the generated ledger dimension account from the originating account if the dimension values are empty for the generated ledger dimension.

For example:

If I give Mainaccount-Fund as a dimension structure.

LedgerDimensionOriginatingAccount = 10200 - 100
LedgerDimensionGeneratedAccount = 10200 - --(empty)

After processing defaulting dimension, a new ledger dimension will be generated and 10200-100 will be a new ledger dimension. I will share the code in the next post how to the dimension defaulting can be done.