May 2008 - Posts
The latest Visual Studio eXtensibility video is up. This one is on integrating with the Error List in Visual Studio 2008. It's quite similar to integrating with the Task List, so keep an eye out for that video which should be coming out soon. Here's a screenshot:

This week's Visual Studio eXtensibility (VSX) video is up. It covers adding a dialog page to configure your Visual Studio Integration Packages. It does this by adding a section into the Tool..Options window. Below is a screenshot:

I've had a lot of traffic to a post from a while back on "Make Your Web Service Proxies Return List<T> Using RegEx (And The Regulator)". In the post, I was converting the arrays that were being generated by the web client proxy into List<T> (Or List(Of T) if you speak VB) and I was using RegEx to do. It was a bit tricky because I had to ignore the object[] arrays that were being used internally in the proxy class and it was a bit kludgy because it had to be run by hand every time you updated the proxy. Later on, I had a follow up for WCF proxies, but it required you to generate your proxy via the command line.
With Visual Studio 2008 and WCF, these problems go away, but you've got to know how to do it. VS 2008 no longer offers an "Add Web Reference" option - it only gives you an "Add Service Reference" (at least that's if you're using a .net 3.0 or later project) which generates a WCF proxy. When you add a service proxy reference, the trick is to open up the Advanced Options:
On the window that loads up, there is a "Collection type" setting (and a "Dictionary collection type" as well if you need that). On this drop down list, simply chance the type to System.Collections.Generic.List:
Updating an Existing Service Reference
If you've already got an existing service reference and you want to change it now to using a List<T>, right click on it and select Configure Service Reference:
When you do this, a window similar to the Service Reference Settings window from above appears, allowing you to do the same as before:

User Defined Functions, or UDFs, provide method-like functionality with TSQL statements. If you've not used them before, you can read more here. In this post I'm going to assume you've got some basic knowledge of UDFs and show how to use them in LINQ To SQL.
First up, you can go and create a simple UDFs. I'm using the tools in Visual Studio to create my UDF but of course you can use Management Studio. My very simple UDF appears as follows:
CREATE FUNCTION dbo.SimpleLookup
(
@SomeInt int
)
RETURNS int
AS
BEGIN
RETURN @SomeInt
END
Once you've created your UDF in the database, the next step is bringing it into the LINQ To SQL designer. If you haven't worked with Stored Procedures or UDFs in LINQ To SQL, you might not have seen the Methods Pane section in the designer. To bring it up, right click in the designer and choose Show Methods Pane:
The Methods Pane appears on the right side of the designer window and now, if you drag Stored Procedures or UDFs from the Server Explorer onto the designer, they will get added into this methods pane, as you can see below:

As you can see on the Properties window, you can change the C# or VB.Net method signature that will be generated to access your UDF. This includes access modifier, inheritance modifier, method name and method return type. When you want to call the UDF from code, you just use it directly within a datacontext, as follows:
using (NorthwindDataContext dc = new NorthwindDataContext())
{
int simpleValue = dc.SimpleLookup(3);
...
But, perhaps even more interesting is that you can use a UDF directly within a LINQ To SQL query, as follows:
using (NorthwindDataContext dc = new NorthwindDataContext())
{
var employees = from e in dc.Employees
where e.EmployeeID > dc.SimpleLookup(2)
orderby e.EmployeeID
select e;
...
when this runs, it will generate the following query:
SELECT [t0].[EmployeeID], [t0].[LastName], [t0].[FirstName], [t0].[Title], [t0].
[TitleOfCourtesy], [t0].[BirthDate], [t0].[HireDate], [t0].[Address], [t0].[City
], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[HomePhone], [t0].[Ext
ension], [t0].[Photo], [t0].[Notes], [t0].[ReportsTo], [t0].[PhotoPath]
FROM [dbo].[Employees] AS [t0]
WHERE ([t0].[EmployeeID]) > [dbo].[SimpleLookup](@p0)
ORDER BY [t0].[EmployeeID]
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [2]
Udi Dahan has an interesting article on the IASA on sprinkling some common sense and some age-old wisdom into new "cutting-edge" thinking. Check it out at Fear Those Tiers
The most recent How Do I video was recently published. It covers adding a custom tool window into the IDE with its own toolbar. The example is simple (just a web browser) but it covers some of the main core concepts. Here's a screenshot:

That's right, the one and only Brad Abrams from Microsoft will be visiting us at the end of June and he'll be giving a talk on the upcoming Microsoft ASP.Net MVC framework.
Here's Microsoft blurb on the MVC framework:
ASP.NET MVC provides a framework that enables you to easily implement the model-view-controller (MVC) pattern for Web applications. This pattern lets you separate applications into loosely coupled, pluggable components for application design, processing logic, and display.
ASP.NET MVC is not a replacement for Webforms. It provides an alternative choice when designing a Web application. Using ASP.NET MVC offers the following advantages:
- It enables you to achieve and maintain a clear separation of concerns
- It facilitates test driven development (TDD)
- It provides more control over the URLs you publish in the application and over the HTML that is emitted by the application
Brad is a real .Net superstar, so don't miss this one out. Here is an extract for his official bio:
Brad Abrams was a founding member of both the Common Language Runtime, and .NET Framework teams at Microsoft Corporation where he is currently the Group Program Manager for the UI Framework and Services team .... Specific technologies owned by this team include ASP.NET, parts of Silverlight, and Windows Forms.
Please RSVP for this event, as we need to determine seating. You can RSVP on the main S.A. Developer event thread or email me using the Contact page on my blog.
Bonus extra - check out the most recent DotNetRocks episode with Brad on .Net 3.5 SP1 and Visual Studio 2008 SP1
One of the features of LINQ queries is Deferred Execution, which Charlie Calvert discusses here with some great examples. This feature can be used to let you create a shared function to handling adding specific functionality to all queries for a specific type. For instance, if we have a simple Northwind DataContext like the following:
then, if we want to write a simple query like the following to find all customers who live in cities starting with an 'L' (or perhaps a less arbitrary query ;->):
IQueryable<Customer> customers = from c in dc.Customers
where c.City.StartsWith("L")
select c;
we can add the Order By inline, as follows:
IQueryable<Customer> customers = from c in dc.Customers
where c.City.StartsWith("L")
orderby c.City // <- inline orderby
select c;
Or we can add the Order By later on, like this:
IQueryable<Customer> customers = from c in dc.Customers
where c.City.StartsWith("L")
select c;
customers = customers.OrderBy(c => c.City);
this is because, until we actually execute the query, using a foreach, or a ToList(), or similar (see Charlie's article for more), we can slice and dice the IQueryable as we like, give or take. This allows for some interesting scenarios, one of which is creating multiple query functions (GetCustomerByName, GetCustomerByCity, etc.), but then sharing the same Order By logic. A sample Order By method could look like:
enum OrderType
{
CompanyName,
ContactName,
City
}
static void AddOrderBy(ref IQueryable<Customer> customerQuery, OrderType orderType)
{
switch (orderType)
{
case OrderType.CompanyName:
customerQuery = customerQuery.OrderBy(c => c.CompanyName);
break;
case OrderType.ContactName:
customerQuery= customerQuery.OrderBy(c => c.ContactName);
break;
case OrderType.City:
customerQuery= customerQuery.OrderBy(c => c.City);
break;
default:
break;
}
}
Then it could be used very easily from select clauses like:
static List<Customer> GetCustomersByName(string companyName, OrderType orderType)
{
using (NorthwindDataContext dc = new NorthwindDataContext())
{
dc.Log = Console.Out;
IQueryable<Customer> customers = from c in dc.Customers
where c.CompanyName.Contains(companyName)
select c;
AddOrderBy(ref customers, orderType);
return customers.ToList();
}
}
static List<Customer> GetCustomersByCity(string city, OrderType orderType)
{
using (NorthwindDataContext dc = new NorthwindDataContext())
{
dc.Log = Console.Out;
IQueryable<Customer> customers = from c in dc.Customers
where c.City.Contains(city)
select c;
AddOrderBy(ref customers, orderType);
return customers.ToList();
}
}
and finally, usage of these methods is as simple as:
customers = GetCustomersByCity("Cape Tow", OrderType.ContactName);
As an alternative extension to this, you can make use of the Dynamic LINQ Query Library from Microsoft (read more here at Scott Guthrie's blog), which would allow you to specify the Order By clauses as strings, as follows:
customers = customers.OrderBy("City");
My latest video is on the Visual Studio Extensibility How Do I series page. This latest video covers writing out to the Output tool window. Here's a screenshot:

Ok, so we all know the old joke about how the entry in the dictionary for "Recursion" says "see...Recursion", but I've never spotted one in a Microsoft library quite this bluntly. It seems the definition for IOleCommandTarget is:
"Enables the dispatching of commands between objects and containers. For more information, see IOleCommandTarget"
Very helpful!