Linq to SQL, aggregates and empty results

Hopefully I’m not the only one having trouble with aggregates, Linq to SQL and empty results. The query I had was something like the following.

var result = (from v in db.Table select v.IntColumn).Max();

This fails with an exception if Table is empty.

The null value cannot be assigned to a member with type
System.Int32 which is a non-nullable value type.

So after some reading on MSDN I found the extension method Queryable.DefaultIfEmpty, it returns a collection with one element that has the default value of the type of the IQueryable<T> if the IQueryable<T> is empty, that looked like it could solve my problem. But I quickly found out that it is not supported by Linq to SQL.

Could not format node 'OptionalValue' for execution as SQL.

So then after reading a blog post about this I ended up with the following query that does what I want.

var result = (from v in db.Table select (int?)v.IntColumn).Max()
    ?? 0;

It has the side effect that the generated SQL query contains an extra nested select but I think that is acceptable.

SELECT MAX([t1].[value]) AS [value]
FROM (
    SELECT [t0].[IntValue] AS [value]
    FROM [Table] AS [t0]
) AS [t1]

MsBuild item evaluation surprise

Solved a problem with a build script last week. I had somehow caused the build to under some conditions take a very long time to start with heavy disk IO. After reviewing some recent changes I found the cause.

I had a ItemGroup that looked something like the following.

<ItemGroup Condition="'$(PathProperty)'!=''">
    <SomeItem Include="$(PathProperty)/**/*.dll"/>
</ItemGroup>

Apparently MsBuild evaluates all ItemGroups even if the condition of the group or item evaluates to false. The result is just discarded if the condition evaluates to false. So the item above included all dll files on the entire hard drive when PathProperty was not set. By trial and error I found out that the condition of Choose elements are evaluated before the items they contain.

So to speed things up I changed the above to the following.

<Choose>
    <When Condition="'$(PathProperty)'!=''">
        <ItemGroup>
            <SomeItem Include="$(PathProperty)/**/*.dll"/>
        </ItemGroup>
    </When>
</Choose>

Is this behaviour obvious to everyone else? Couldn’t find anything about it while reading the conditions documentation nor the documentation on items and properties on MSDN.