LINQed IN

Blog by Troy Magennis on Software Architecture, Development and Management

About the author

Troy Magennis is a software developer living in Seattle, WA. Troy is a Microsoft MVP, the author of many articles, and the founder of HookedOnLINQ.com, a LINQ specific wiki reference site.
E-mail me Send mail

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

ExecuteQuery Tooltip - The worlds longest?

I had a need to execute a SQL statement using LINQ to SQL. Its a long story, but I couldn't use the LINQ to SQL Designer because I was calling a SQL Server 2005 System View. So, I just decided to use the DataContext.ExecuteQuery method. It was a welcome surprise when the intellisense tooltip filled the screen for the first parameter "elementType" -

ExecuteQuery_Tooltip

Actually, the tooltip really helped. It explains the rules and priority of how the return resultset is mapped to the type you specify. To paraphrase, even though my type doesn't have LINQ to SQL attributes on each property, the system will still attempt to match properties to result columns using a variety of methods.

  1. If a field or property is matched to a specific column name, that column is expected in the result set
  2. If the field or property is not matched, a column is expected with the same name in the result set (first Case Sensitive search, then case in-sensitive search)

It goes onto specify the rules about change tracking, primary keys, etc.

A lot to read, but definitely saved me a having to hunt around for the necessary information. Nice work to whoever spent the extra time going to this detail; it shows they really thought about what someone would need when they used this method for the first time.

It could have been "elementType: The element type." if i'd been writing it :-)

Troy.


Categories: C# | LINQ
Posted by t_magennis on Tuesday, July 15, 2008 10:46 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Visualizing Code Change Impact and Database Dependencies

Its often difficult on large projects to keep track of all the additions as a system grows. When a project grows, it gets more difficult to keep all system drawings accurate and correct. If a drawing isn't automatically generated, then you can have little faith that it is absolutely up-to-date.

The alternative is to write tools that examine the code and draw representations of the systems continuously. This can be part of a nightly build, or a tool that can be run on-demand in order to make better decisions, resolve design issues early, and identify impact of changes.

In this instance I was having trouble keeping up with what Web Services we had; What Stored Procedures they relied upon, and what SQL Server tables those Stored Procedures depended upon.

The application we wrote in a couple of days simply hunts through all *.cs files and uses Regular Expressions to find applicable code. It then uses Microsoft Research's Graph Drawing Tool "GLEE" to visually represent it. GLEE is incredibly easy to use and integrate. The following screen-shot (with the sensitive names removed) took less than 15 lines of code to produce (and a few hundred to do the Regular Expression hunting).

Service_Explorer

A side-benefit of this tool is that it forces the team to conform to the coding standards. If they want their new code to be incorporated into the latest drawings, follow the patterns provided.

Its great to come into work each morning and see what has been added, and to ensure that the cross-coupling even at the database level isn't going to cause use duress later in the project. We can quickly see what a DB schema change will impact. Sleeping much better now....

Troy.


Posted by t_magennis on Tuesday, July 15, 2008 10:30 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Determining SQL Server Object Dependencies for a Stored Procedure or Other Database Object Name

Finding what dependencies a Stored Procedure has on underlying tables, views, functions, etc is often necessary when trying to assess the impact of a change. SQL Server has built-in functions that will indicate in most cases a dependency for any object in the database. The system view "sys.sql_dependencies" is viewed with skepticism by some people who have obviously been bitten in the past.

In order to see for myself the results, I wrote a simple helper class, and thought i'd share the boilerplate code to start you off here (I may clean it up and share it as a library, email me if you have difficulty getting it running). Its a rough prototype, but it is returning good results for my purposes.

Note: This code requires Visual Studio 2008. It uses LINQ to SQL in a very loose way due to the LINQ to SQL Designer not listing the System Views and Functions. Its a good example of just how flexible LINQ to SQL is though.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using System.Configuration;

namespace DatabaseDependencyCrawler
{
    public class SysDependsResult
    {
        public int referenced_major_id { get; set; }
    }

    public class ObjectInfoResult
    {
        public int id { get; set; }
        public string name { get; set; }
        public string xtype  { get; set; }
        public DateTime crdate { get; set; }
    }

    public class DatabaseDependencyCrawler
    {
        public List<DatabaseDependencyEntity> GetDBObjectDependencies(string connectionString, string name)
        {
            // the system views built-into SQL Server 2005
            string dependsQuery = "select referenced_major_id from sys.sql_dependencies where object_id = object_id('{0}')";
            string objectInfoQuery = "select * from sys.sysobjects where id in ( {0} )";

            List<DatabaseDependencyEntity> result = new List<DatabaseDependencyEntity>();

            // find the list of dependencies based upon a database object's name
            DataContext context = new DataContext(connectionString);

            var dependencies = (IEnumerable<dependencies>)context.ExecuteQuery(
                typeof(SysDependsResult),
                string.Format(dependsQuery, name), 
                new object[] { });

            // build a list of object_is's to we can ask for their name in a second query
            StringBuilder ids = new StringBuilder();
            foreach (SysDependsResult d in dependencies)
            {
                if (ids.Length > 0)
                     ids.Append(",");

                ids.Append(d.referenced_major_id);
            }

            // if any records were found...lookup the names of those id's comma separated
            if (ids.Length > 0)
            {

                IEnumerable<ObjectInfoResult> objects = (IEnumerable<ObjectInfoResult>)context.ExecuteQuery(typeof(ObjectInfoResult),
                    string.Format(objectInfoQuery, ids.ToString()),
                    new object[] { });

                foreach (ObjectInfoResult o in objects)
                {
                    result.Add (
                        new DatabaseDependencyEntity {
                            DatabaseConnectionString = connectionString,
                            SourceObject = name,
                            Dependent = o
                        });
                }
            }
        
            return result;
        }
    }
}

Categories: C# | LINQ | Resources
Posted by t_magennis on Tuesday, July 15, 2008 5:34 AM
Permalink | Comments (3) | Post RSSRSS comment feed

Tips for WinForms Memory and Painting Debugging

Every now and then I come across a Windows Forms application that has memory leak, or graphic resource leak issues. In managed environments like .NET, some developers overlook that many components wrap un-managed finite resources.  I worked with a fellow developer Mike Zhang today, and because of the difficulties in replicating the issue, we decided that a full pass through the entire source code fixing these issues was our best shot at solving a niggling production issue. After today, here are our top 4 tips and the first steps to ensuring you have a well behaved Windows Forms .NET application.

Begin Update / End Update (Blank, unpainted regions of the screen)

Many Windows controls have a BeginUpdate and EndUpdate methods. These inhibit any Paint events being called when a lot of data is being added to a ListView for example. Big trouble occurs if an EndUpdate isn’t called matching a BeginUpdate! Most general case, is an exception occurs after the begin, but before the EndUpdate gets called.

To Fix: Do a solution wide search for “BeginUpdate”; Go through the result list (yes, EVERY one of them) and ensure that a the EndUpdate is wrapped in a Finally block.

BAD

   1:  this.BeginUpdate();
   2:  // lots of work, including work that may throw an exception!
   3:  // ...
   4:  this.EndUpdate();

GOOD

   1:  this.BeginUpdate();
   2:  try
   3:  {
   4:       // lots of work, including work that may throw an exception!
   5:  }
   6:  finally
   7:  {
   8:      // EndUpdate called even in the case of an Exception in the lots of work above.
   9:      this.EndUpdate();
  10:  }

Pen, Brush and Graphic Resources (Resource leak)

Even in .NET, a lot of managed code uses unmanaged resources. These managed wrappers implement the IDisposible pattern, where the Dispose method nicely releases all unmanaged resources. However – What if Dispose doesn’t get called? Either because Garbage Collection in .NET is happens on its own non-deterministic timetable, some external reference keeps an object alive, or an exception occurs and Dispose is never called. This manifests itself as areas that don’t draw properly or have an enclosed red cross.

To Fix: Do a solution wide search for “Graphic ”, “Pen “ and “Brush “; Go through the result list (yes, EVERY one of them) and ensure that the scope of the Brush, Pen or Graphic is within a using clause, or a try/finally block.

Read: "using" statement reference on MSDN: http://msdn2.microsoft.com/en-us/library/yh598w02.aspx

BAD

   1:      Graphics g = Graphics.FromImage(sourceImage);
   2:      Pen pen = new Pen();
   3:      // lots of work, including work that might fail
   4:      g.DrawRectangle(pen, 10, 10, 100, 100);
   5:      throw new Exception();
   6:      pen.Dispose(); // never called
   7:      g.Dispose(); // never called

GOOD

   1:      using(Graphics g = Graphics.FromImage(sourceImage))
   2:      {
   3:          using(Pen pen = new Pen())
   4:          {
   5:              // lots of work, including work that might fail
   6:              g.DrawRectangle(pen, 10, 10, 100, 100);
   7:              throw new Exception();
   8:           } // calls pen.Dispose() in all cases
   9:      } // calls g.Dispose() in ALL cases

Manual Event Wiring Up and Object Lifetime (memory and resource leak)

This is without a doubt the most common (and some say only common) memory leak on .NET applications. If your component subscribes to an event in ANOTHER component or class, you must –

a) Unhook yourself in your Dispose method for the form or class you subscribed FROM

b) Avoid multiple hookups to an event if your form is opened, or called multiple times

Tips:

a) Hookup events using the Forms designer when possible; This automatically handles events in the proper way

b) To be sure multiple hookups don’t accidently occur, remove yourself from an event before hooking your event up (this is safe, even the first time) –

BAD
ValidationGlobalManager.OnValidate += new My ValidationHandler(MyValidationFunction);


GOOD
  ValidationGlobalManager.OnValidate -= new My ValidationHandler(MyValidationFunction);
  ValidationGlobalManager.OnValidate += new My ValidationHandler(MyValidationFunction);

c) If you hook up an event outside of InitializeComponent (i.e. NOT through the forms designer), then YOU are responsible for unhooking your event in the Dispose() method of your form.

OnPaint and OnDraw Event Handlers - Call the base. implementation in all cases (unpredictable drawing behavior)

Many controls allow you to implement your own OnDraw and OnPaint event handlers. However, the base.OnDraw(); or base.OnPaint(); methods MUST be called under all conditions, even in the case your code fails with an exception.

To Fix: Do a solution wide search for “OnDraw ” and “OnPaint“; Go through the result list (yes, EVERY one of them) and ensure that

a) the base call is first, so it always runs, OR

b) the base call is protected with a try/finally block

Mike and Troy.


Tags: ,
Categories: C#
Posted by t_magennis on Wednesday, April 09, 2008 4:23 AM
Permalink | Comments (0) | Post RSSRSS comment feed

AForge - Image, Math, Vision, Neuro and Computer Learning Libraries

I'm probably the last to know, but I had a real need for some solid imaging and graphic library source code. I was incredibly impressed with the AForge library by Andrew Kirillov.

Get the source and library here: AForge on code.google.com

AForge.NET is a C# framework designed for developers and researchers in the fields of Computer Vision and Artificial Intelligence - image processing, neural networks, genetic algorithms, machine learning, etc.

At this point the framework is comprised of 5 main and some additional libraries:

  • AForge.Imaging – a library for image processing routines and filers;
  • AForge.Neuro – neural networks computation library;
  • AForge.Genetic – evolution programming library;
  • AForge.Vision – computer vision library;
  • AForge.Machine Learning – machine learning library.

Releases are frequent; The code clearly written; Good samples - all round a great project. Nice work to all those involved.

Troy.


Tags: ,
Categories: C#
Posted by t_magennis on Wednesday, April 09, 2008 4:18 AM
Permalink | Comments (0) | Post RSSRSS comment feed

LINQ Reference Mug and Mousemat

I put together a mug and mouse-mat design with LINQ Reference information. I wanted to have a list of the standard query operators and the new C# Query Expression Syntax on hand at all times. My only concern is spilling coffee over the keyboard when looking up the "Join" syntax reference!

combo_mug_front combo_mug_back sqo_mousepad

They take information from the HookedOnLINQ Wiki website, and you can buy them for $14.99 if you think they might be useful.

Buy a LINQ SQO and Query Expression for $14.99 + shipping

Buy a LINQ SQO Mousemat for $14.99

I don't have a VB equivalent yet, and I'd be interested if anyone has ideas for improving them or can point out errors or omissions.

Troy.


Tags: ,
Categories: C# | LINQ | HookedOnLINQ
Posted by t_magennis on Friday, February 08, 2008 4:35 AM
Permalink | Comments (0) | Post RSSRSS comment feed

CodeCamp 2008 Seattle Notes

I was fortunate enough to attend Code Camp in Seattle last weekend. It was great to see the event attended by around 300 keen developers.

I took notes throughout some sessions, and posted full details the HookedOnLINQ.com website.

By far, the Parallel LINQ session was a standout. I was surprised just how cleanly the ParallelFx team have committed to making multiple processor development mainstream. This is a library and feature set that is important to watch.

Troy.


Tags:
Categories: C# | LINQ | Resources
Posted by t_magennis on Thursday, January 31, 2008 4:42 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Null Coalescing Operator

This came up today in the office, so I thought i'd post a reminder of a useful operator in C# that first appeared in C# 2.0.

When Nullable Types were introduced, Microsoft also added an operator to make dealing with null values easier. This avoids a lot of if/else checking for null values.

The normal form is:  [variable] ?? [value if variable is null]

A simple example is when dealing with nullable types, like nullable int values -

int? i = null;
int? j = 42;

int result1 = i ?? 0; // result1 is 0
int result2 = j ?? 0; // result2 is 42

The results are: result1 = 0 (because i was null), and result2 = 42 (because j had a value).

The null coalescing operator removes a lot of the clutter of testing a variable for null and assigning a default value. This is often necessary when casting a nullable type back to its non-nullable counterpart.

To read more see lots of references on this Google  search.

Troy.


Tags:
Categories: C#
Posted by t_magennis on Tuesday, November 20, 2007 5:05 AM
Permalink | Comments (0) | Post RSSRSS comment feed

The Null Coalescing Operator - ??

This came up today in the office, so I thought i'd post a reminder of a useful operator in C# that first appeared in C# 2.0.

When Nullable Types were introduced, Microsoft also added an operator to make dealing with null values easier. This avoids a lot of if/else checking for null values.

The normal form is:  [variable] ?? [value if variable is null]

A simple example is when dealing with nullable types, like nullable int values -

int? i = null;
int? j = 42;

int result1 = i ?? 0; // result1 is 0
int result2 = j ?? 0; // result2 is 42

The results are: result1 = 0 (because i was null), and result2 = 42 (because j had a value).

The null coalescing operator removes a lot of the clutter of testing a variable for null and assigning a default value. This is often necessary when casting a nullable type back to its non-nullable counterpart.

To read more see lots of references on this Google  search.

Troy.


Tags:
Categories: C#
Posted by t_magennis on Tuesday, November 20, 2007 5:04 AM
Permalink | Comments (0) | Post RSSRSS comment feed