Linq: Using Group By with Multiple Columns

I have a group of classes that I build to get metadata from the database to use with my code generators. The class has the following structure:

public class ConstraintMetadata
{
    public string ConstraintName { get; set; }

    public string ColumnName { get; set; }

    public string ConstraintType { get; set; }

    public string TableName { get; set; }
}

I wanted to write a group by clause using Linq to group the objects I retrieved from the db by TableName, ConstraintName and ConstraintType. This would allow me to have one object for each constraint with a list of all the columns. Since Linq only allows one object in the group by clause the way out is to create an anonymous object with all the properties I want.

var constraints = from c in constraintsMetadata
                  group c by new
                             {
                                 c.TableName, 
                                 c.ConstraintType, 
                                 c.ConstraintName
                             } into g
                      select new
                      {
                          g.Key.ConstraintName,
                          g.Key.ConstraintType,
                          g.Key.TableName,
                          Columns = g.Select(x=>x.ColumnName).ToList()
                      };

Now, if I want to get all the constraints for a table and print it to the console window I can do this:

var tableConstraints = constraints.Where(x => x.TableName == table.Name);

foreach (var tableConstraint in tableConstraints)
{
    Console.Out.WriteLine("Constraint Name:{0}, Table:{1}, Type:{2} Columns:", 
        tableConstraint.ConstraintName , 
        tableConstraint.TableName, 
        tableConstraint.ConstraintType);
    foreach (var column in tableConstraint.Columns)
    {
        Console.Out.WriteLine(column);
    }
}

 

Find out the calling method

This is one that I found really interesting. I needed to log which methods were calling a certain method, I knew that reflection was the answer but I never thought it would be so easy.

Have you used the CallStack window on your VisualStudio when you are debugging? Well, all that information is available through the System.Diagnostics.StatckTrace class. This means that you have access to method calling stack to do whatever you like.

The StackTrace is composed of an array of StackFrames which represent each method on the stack.

To demonstrate this I’ll create a class with four methods (Method1, Method2, Method3, Method4) which will be called in the following order:

Main -> Method1 -> Method2 -> Method3 -> Method4

class Program
{
    static void Main(string[] args)
    {
        StackTraceTest stt = new StackTraceTest();
        stt.Method1();
    }
}

class StackTraceTest
{
    public void Method1()
    {
        Console.Out.WriteLine("Inside Method1");
        Method2();    
    }

    private void Method2()
    {
        Console.Out.WriteLine("Inside Method2");
        Method3();
    }

    private void Method3()
    {
        Console.Out.WriteLine("Inside Method3");
        Method4();
    }

    private void Method4()
    {
        Console.Out.WriteLine("Inside Method4");
        StackTrace st = new StackTrace();
        StackFrame[] frames = st.GetFrames();
        for (int i = 0; i < frames.Count(); i++)
        {
            Console.Out.WriteLine("StackTrace info: Index: {0}/Method: {1}", 
                i, frames[i].GetMethod().Name);
        }
    }
}

Each method displays a message on the console letting you know that it has been invoked. When the program gets to Method4 it will print the name of the methods on the stack.

Here is the output:

Put a break point on the end of the Method4 and you can take a look at VisualStudios CallStack window to compare with the console output.

As a test you might want to move the StackTrace code to the other methods to see that it will show all the method that led to method currently executing.

For more information look at the StackFrame and MethodBase classes at MSDN.