Little known new features in Visual Studio 2012

Very poorPoorAverageGoodExcellent (9 votes) 
Loading...Loading...

Visual Studio 2012 RC is out since last week, and even though I didn’t have much time to play with it yet, I think I like it so far. Lots of things have already been said about the design, and about the most important new features, but there are also many smaller and less remarkable improvements that make life easier for us. Since I have seen little or nothing written about those, I thought I would make a list of what I noticed so far.

Better Edit and Continue: improved debug experience with anonymous methods

Edit and continue is a very useful feature that has been present in Visual Studio for a long time. It’s great when you need to fix some code in the middle of a step-by-step debugging session without restarting the application completely. This feature has always had a limitation: you couldn’t use it in a method that contained an anonymous method:

Modifying a ’method’ which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled.

Before .NET 3.5, it wasn’t really a problem since anonymous methods were not very common, but since Linq was introduced and lambda expressions became more widely used, this limitation began to grow more and more annoying.

Well, good news: Visual Studio 2012 fixed that! You can now use Edit and Continue in a method that contains lambda expressions or Linq queries. Note that the limitation hasn’t completely disappeared: you still can’t modify a statement that contains an anonymous method. Note the slightly different error message:

Modifying a statement which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled.

But you can modify everything else in the method body, which is a great improvement. Note that editing a method that contains anonymous types is also supported, as long as you don’t modify the anonymous type itself.

Optimized event handler autocompletion

Visual Studio has a nice autocompletion feature that allow you to generate an event handler automatically when you type += and Tab after an event name :

image

But the new EventHandler(…) part is redundant, because since C# 2, method groups are implicitly convertible to compatible delegate types. Visual Studio 2012 fixes this and generates the shorter form:

image

OK, this is a very small change, but the previous behavior was really annoying me… I had actually suggested this improvement on Connect, so I’m glad to see that it was implemented.

Improved Find/Replace

The Find dialog in Visual Studio had not seen any improvement for as long as I can remember (probably since VS2003 or VS2005), so it was time for a change… In VS2012, it has been replaced with the Quick Find feature from the Productivity Power Tools extension. It appears as a small panel in the top right corner of the text editor, much less obtrusive than the old dialog:

image

It provides the following features:

  • incremental search (matches are highlighted as you type in the search box)
  • quick access to options such as match case, match whole word, or regex through the search field dropdown
  • support for .NET regular expressions (the old Find dialog was using a different kind of regex, not fully compatible with the .NET regex syntax)

If for some reason you need the full Find dialog, it’s still there: there’s a menu item to access it in the search field dropdown.

Quick launch

Where’s that command again? In the Debug menu or the Project menu? I can’t remember, and I don’t know the keyboard shortcut…

Sounds familiar? For me it does… Visual Studio has so many features that sometimes it can be hard to find what you’re looking for. That’s why the new Quick Access feature is a very welcome addition; it appears as a search box in the top right corner of the IDE, and allows you to type what you want to do:

image

Again, this feature comes from the Productivity Power Tools extension, and has been included in Visual Studio itself. It has also been given a more prominent place in the IDE (in VS2010 it was only accessible through the Ctrl+Q shortcut).

Smarter Solution Explorer

The Solution Explorer used to show only the files in your project, but nothing about what was in the files; If you want to see the classes and members, you had to switch to the Class View. Visual Studio 2012 changes that: now you can see what is declared in a file, just by expanding the node in the Solution Explorer:

image

This feature had been in Eclipse for a long time, so it was time for Visual Studio to catch up Clignement d'œil.

A few other interesting features of the new Solution Explorer:

  • Scope to This: allows to re-root the tree to a specific node (e.g. if you want to see only the content of a folder). The re-rooted tree can be viewed in a separate view.
  • Pending Changes Filter: show only pending changes (if source control is active for the current project)
  • Open Files Filter: show only open files
  • Sync With Active Document: quickly locate the current document in the Solution Explorer (very useful for large solutions)

And yes, that’s yet another feature that comes from Productivity Power Tools (it was known as the Solution Navigator), with a few improvements.

ALL CAPS MENUS

Menus in VS2012 are in ALL CAPS, and it’s not exactly the most popular change… there has been tons of negative feedback about this! Frankly, I’m a bit surprised that people pay so much importance to such an insignificant detail, when there are so many more important things to discuss. Personally, I found it a bit unsettling when I saw the first screenshots, but when I got my hands on the RC I found that it didn’t bother me at all. I guess most people will just get used to it in the end…

Anyway, the reason I mention this is to say that if you really don’t like the ALL CAPS menus, you can get the normal casing back with a simple registry tweak. Just open regedit, go to the HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\General key, create a DWORD value named SuppressUppercaseConversion and set it to 1.

kick it on DotNetKicks.com

[Entity Framework] Using Include with lambda expressions

Very poorPoorAverageGoodExcellent (13 votes) 
Loading...Loading...

I’m currently working on a project that uses Entity Framework 4. Even though lazy loading is enabled, I often use the ObjectQuery.Include method to eagerly load associated entities, in order to avoid database roundtrips when I access them:

var query =
    from ord in db.Orders.Include("OrderDetails")
    where ord.Date >= DateTime.Today
    select ord;

Or if I also want to eagerly load the product:

var query =
    from ord in db.Orders.Include("OrderDetails.Product")
    where ord.Date >= DateTime.Today
    select ord;

However, there’s something that really bothers me with this Include method: the property path is passed as a string. This approach has two major drawbacks:

  • It’s easy to make a mistake when typing the property path, and since it’s a string, the compiler doesn’t complain. So we get a runtime error, rather than a compilation error.
  • We can’t take advantage of IDE features like Intellisense and refactoring. If we rename a property in the model, automatic refactoring won’t check the content of the string. We have to manually update all calls to Include that refer to this property, with the risk of missing some of them in the process…

It would be much more convenient to use a lambda expression to specify the property path. The principle is well known, and frequently used to avoid using a string to refer to a property.

The trivial case, where the property to include is directly accessible from the source, is pretty easy to handle, and many implementation can be found on the Internet. We just need to use a method that extracts the property name from an expression :

    public static class ObjectQueryExtensions
    {
        public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, Expression<Func<T, object>> selector)
        {
            string propertyName = GetPropertyName(selector);
            return query.Include(propertyName);
        }

        private static string GetPropertyName<T>(Expression<Func<T, object>> expression)
        {
            MemberExpression memberExpr = expression.Body as MemberExpression;
            if (memberExpr == null)
                throw new ArgumentException("Expression body must be a member expression");
            return memberExpr.Member.Name;
        }
    }

Using that extension method, the code from the first sample can be rewritten as follows:

var query =
    from ord in db.Orders.Include(o => o.OrderDetails)
    where ord.Date >= DateTime.Today
    select ord;

This code works fine, but only for the simplest cases… In the second example, we also want to eagerly load the OrderDetail.Product property, but the code above can’t handle that case. Indeed, the expression we would use to include the Product property would be something like o.OrderDetails.Select(od => od.Product), but the GetPropertyName method can only handle property accesses, not method calls, and it works only for an expression with a single level.

To get the full path of the property to include, we have to walk through the whole expression tree to extract the name of each property. It sounds like a complicated task, but there’s a class that can help us with it: ExpressionVisitor. This class was introduced in .NET 4.0 and implements the Visitor pattern to walk through all nodes in the expression tree. It’s just a base class for implementing custom visitors, and it does nothing else than just visiting each node. All we need to do is inherit it, and override some methods to extract the properties from the expression. Here are the methods we need to override:

  • VisitMember : used to visit a property or field access
  • VisitMethodCall : used to visit a method call. Even though method calls aren’t directly related to what we want to do, we need to change its behavior in the case of Linq operators: the default implementation visits each parameter in their normal order, but for extension method like Select or SelectMany, we need to visit the first parameter (the this parameter) last, so that we retrieve the properties in the correct order.

    Here’s a new version of the Include method, along with the ExpressionVisitor implementation:

        public static class ObjectQueryExtensions
        {
            public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, Expression<Func<T, object>> selector)
            {
                string path = new PropertyPathVisitor().GetPropertyPath(selector);
                return query.Include(path);
            }
    
            class PropertyPathVisitor : ExpressionVisitor
            {
                private Stack<string> _stack;
    
                public string GetPropertyPath(Expression expression)
                {
                    _stack = new Stack<string>();
                    Visit(expression);
                    return _stack
                        .Aggregate(
                            new StringBuilder(),
                            (sb, name) =>
                                (sb.Length > 0 ? sb.Append(".") : sb).Append(name))
                        .ToString();
                }
    
                protected override Expression VisitMember(MemberExpression expression)
                {
                    if (_stack != null)
                        _stack.Push(expression.Member.Name);
                    return base.VisitMember(expression);
                }
    
                protected override Expression VisitMethodCall(MethodCallExpression expression)
                {
                    if (IsLinqOperator(expression.Method))
                    {
                        for (int i = 1; i < expression.Arguments.Count; i++)
                        {
                            Visit(expression.Arguments[i]);
                        }
                        Visit(expression.Arguments[0]);
                        return expression;
                    }
                    return base.VisitMethodCall(expression);
                }
    
                private static bool IsLinqOperator(MethodInfo method)
                {
                    if (method.DeclaringType != typeof(Queryable) && method.DeclaringType != typeof(Enumerable))
                        return false;
                    return Attribute.GetCustomAttribute(method, typeof(ExtensionAttribute)) != null;
                }
            }
        }
    

    I already talked about the VisitMethodCall method, so I won’t explain it further. The implementation of VisitMember is very simple: we just push the member name on a stack. Why a stack ? That’s because the expression is not visited in the order one would intuitively expect. For instance, in an expression like o.OrderDetails.Select(od => od.Product), the first visited node is not o but the call to Select, because what precedes it (o.OrderDetails) is actually the first parameter of the static Select method… To retrieve the properties in the correct order, we put them on a stack so that we can read them back in reverse order when we need to build the property path.

    The GetPropertyPath method probably doesn’t need a long explanation: it initializes the stack, visits the expression, and builds the property path from the stack.

    We can now rewrite the code from the second example as follows:

    var query =
        from ord in db.Orders.Include(o => OrderDetails.Select(od => od.Product))
        where ord.Date >= DateTime.Today
        select ord;
    

    This method also works for more complex cases. Let’s add a few new entities to our model: one or more discounts can be applied to each purchased product, and each discount is linked to a sales campaign. If we need to retrieve the associated discounts and campaigns in the query results, we can write something like that:

    var query =
        from ord in db.Orders.Include(o => OrderDetails.Select(od => od.Discounts.Select(d => d.Campaign)))
        where ord.Date >= DateTime.Today
        select ord;
    

    The result is the same as if we had passed “OrderDetails.Discounts.Campaign” to the standard Include method. Since the nested Select calls impair the readability, we can also use a different expression, with the same result:

    var query =
        from ord in db.Orders.Include(o => o.OrderDetails
                                            .SelectMany(od => od.Discounts)
                                            .Select(d => d.Campaign))
        where ord.Date >= DateTime.Today
        select ord;
    

    To conclude, I just have two remarks regarding this solution:

    • A similar extension method is included in the Entity Framework Feature CTP4 (see this article for details). So it is possible that it will eventually be included in the framework (perhaps in a service pack for .NET 4.0 ?).
    • Even though this solution targets Entity Framework 4.0, it should be possible to adapt it for EF 3.5. The ExpressionVisitor class is not available in 3.5, but there is another implementation of it in Joseph Albahari’s LINQKit. I didn’t try it, but it should work the same way…

    kick it on DotNetKicks.com

css.php