Thursday, October 29, 2009

In my article XXX I talked about how to improve the speed of LINQ to SQL queries with multiple one to many associations. The post propsed to use the following statement.
var orderItems= db.OrderItems
.Where(oi => orders.Select(o => o.ID).Contains(oi.OrderID)).ToList();
foreach (var o in orders)
{
var oClosure = o;
oClosure.OrderItems.SetSource
(orderItems.Where(oi => oi.OrderItemID == cClosure.ID));
}
one more tips here is to store the result of orderItems in a Dictionary using .GroupBy() and .ToDictionary(). If you do not do that you will eventually get a performance problem because you do a linear search inside a loop -- basically you will get a O(n^2) performance for your database retrievals -- not very good. If you use a dictionary lookup you will get something close too O(n) for the foreach loop.

Do not forget to check if you have matches for the key before you use it inside the foreach. If you do not have a match you should use something like oClosure.OrderItems.SetSource(Enumerable.Empty());.

Friday, October 16, 2009

SQL to Linq Performance: Retrieving Multiple One-to-Many Associations without Multiple Round Trips

I have been using SQL to Linq for a while. It is a fairly straight forward framework for retrieving data for my data access layer. The Linq syntax makes it very easy to read while allowing for complex expressions.

Unfortunately, the performance may be really bad in some cases. This is typically because of lazy loading where a round trip is required per row because associated data are loaded. The typical example from the Northwind database is a Customer with multiple Orders. All the Customers are retrieved in one go, however for each customer the associated orders are retrieved in one SQL request. This will generate one SQL request for the customers and then n for the orders. This is hopeless. Fortunately, Microsoft provided us with the DataLoadOptions.LoadWith method. In this case, the following statements solves the problem:
Northwnd db = new Northwnd(@"c:\northwnd.mdf");
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith(c => c.Orders);
db.LoadOptions = dlo;
But what happens if each order has a set of associations? Lets say each order has a collection of OrderItems. You will end up with a round trip to the database for each order. Each round trip will retrieve the associated OrderItems.

So what do you do? You may try to add a second LoadWith statement... but it turns out that this is not supported by Linq to SQL. So if you add the second LoadWith, the framework will do what you tell it. However, it will use multiple SQL statements. So what is the point then?

In order to fix this, use this code:
var orderItems= db.OrderItems.Where(oi => orders.Select(o => o.ID).Contains(oi.OrderID)).ToList();
foreach (var o in orders)
{
var oClosure = o;
oClosure.OrderItems.SetSource
(
orderItems.Where(oi => oi.OrderItemID ==
cClosure.ID));

}
So basically, by pre-fetching orderItems and manually setting the source by using SetSource, the number of round trips are reduced to two. Great? ;-)

Saturday, October 10, 2009

SQL Server 2008 SP1 brok my SQL Server

After installing SQL Server 2008 SP1 my SQL Server stopped working. The SQL Server reported the following in the log file:
2009-10-10 19:01:09.15 spid7s Error: 15404, Severity: 16, State: 19.
2009-10-10 19:01:09.15 spid7s Could not obtain information about Windows NT group/user 'XXX\XXX', error code 0x5.
2009-10-10 19:01:09.15 spid7s Error: 912, Severity: 21, State: 2.
2009-10-10 19:01:09.15 spid7s Script level upgrade for database 'master' failed because upgrade step 'sqlagent100_msdb_upgrade.sql' encountered error 15404, state 19, severity 16. This is a serious error condition which might interfere with regular operation and the database will be taken offline. If the error happened during upgrade of the 'master' database, it will prevent the entire SQL Server instance from starting. Examine the previous errorlog entries for errors, take the appropriate corrective actions and re-start the database so that the script upgrade steps run to completion.
2009-10-10 19:01:09.16 spid7s Error: 3417, Severity: 21, State: 3.
2009-10-10 19:01:09.16 spid7s Cannot recover the master database. SQL Server is unable to run. Restore master from a full backup, repair it, or rebuild it. For more information about how to rebuild the master database, see SQL Server Books Online.
2009-10-10 19:01:09.16 spid7s SQL Trace was stopped due to server shutdown. Trace ID = '1'. This is an informational message only; no user action is required.
2009-10-10 19:01:09.84 Server The SQL Server Network Interface library successfully deregistered the Service Principal Name (SPN) [ MSSQLSvc/XXX ] for the SQL Server service.
No luck? Then I tried to run the SQL instance as a privileged user, and now it works again. It looks like the upgrade script required some extra permission.

Friday, October 9, 2009

ReSharper 5.0 is comming

According to the official blog for JetBrains, ReShaper 5.0 is just around the corner. I am looking forward to this. The new release will provide improvements such as:
  • Web Development. Web developers have long been asking for top-class support, so we’re starting to deliver on the promise with a pack of features for HTML, ASP.NET, and ASP.NET MVC.
  • Project and Team. This is a valuable addition for developers having to explore much unfamiliar code and/or perform batch modifications in large-scale projects. With access to and navigation within external sources, structured patterns for searching and customizing code, and location/namespace synchronization tools working in batch mode, you can handle your colossal solutions easier.
  • Code Analysis. In addition to fresh code inspections, ReSharper 5.0 presents multiple functional style “enumeration to LINQ” transformations, accepts warnings and suggestions into the “Errors in Solution” tool window, and introduces two major features to track what’s going on with your calls and data throughout application execution.
  • Visual Studio 2010 and Tools. We’re on the run to support Visual Studio 2010 earlier than ever. More info on that when VS2010 Beta2 comes out. Of course, Visual Studio 2008 is supported as well.

Tuesday, October 6, 2009

ITransformableFilterValues and List View Web Part in SharePoint

After preparing a new web part filtering that implements ITransformableFilterValues I though I was near a solution: I wanted to filter a standard Sharepoint list by a set of values that I provided in my filter web part. Now it looks like the standard list view web part only accepts the one value, not multiple. So if you want it to show all rows where the value is A or B, then you are out of luck.

So what can you do? You try to find a different list view web part? That should be easy. After looking for a few days I am still out of luck.

Any suggestions?

Wednesday, August 19, 2009

Team Build Tray

I just tried Team Build Tray 1.0.4, but it was a big disappointment. It shows you the status of your builds, but only for one of your projects. I want them all!

I guess I have to stick to the one bundled with TFS Power Toys!

Tuesday, August 18, 2009

Team Foundation Build -- running build script from command line

Often you want to verify that your build will work correctly on your build machine before you do a commit. In Visual Studio you can run all your tests etc, but your build script will propably do some things such as settings up databases. This can be archived this way:
Open the DOS command window
Go to the TFS Build directory where TFSBuild.proj is located
Enter "msbuild /p:SolutionRoot=..\..\.. /t:DesktopRebuild"

The solution root may have to be changed depending on how you mounted the workspace.

I usually keep a shortcut on my desktop that I can just double click on for a fast compile.