Tuesday, September 8, 2009

Filtering with LINQ

I recently refactored the display of data on a web page (in a Datagrid) from using a DataSet as the source to a List. As part of the original functionality, the list of items being displayed could be filtered based on selections that the user made. I decided to take advantage of the built in LINQ extension features for Lists to accomplish the filtering. The two extensions that I leveraged were the TrueForAll and Exists extensions.

 

In my first scenario, I have an object (Resource) that have a sub-List of times (TimeEntries) that represent their availability within a day. I need to filter the list to include all Resources in the list where their TimeEntries are not off (e.g. not on vacation, jury duty, break, etc.) In order to build that I used the TrueForAll extension that was examining a boolean method on the Resource object as shown below:

 

return resources.FindAll(r => r.Entries.TrueForAll(e => e.IsRegEntry()));





Additionally, I needed to filter the list to include the Resource if at least one of their entries was an Off entry, so for that I used the Exists extension as seen below:


 



return resources.FindAll(r => r.Entries.Exists(e => e.IsOffEntry()));





I am continually amazed at the power of LINQ and how it can make what was once fairly complex seem so much simpler and easier to understand. If you have an opportunity to check it out, I would highly recommend it.

Wednesday, September 2, 2009

SQL Server 2008 – Assign a default value to a local variable

I just discovered today, that SQL Server 2008 allows you to assign a default value to a local variable. I was not aware that this functionality had been added until I had a stored procedure I was working with on my local SQL 2008 database and tried to execute it on the shared development database, which is still running SQL 2005 and I received the following error:

Msg 139, Level 15, State 1, Procedure apGetRollCallData, Line 0
Cannot assign a default value to a local variable.
Msg 139, Level 15, State 1, Procedure apGetRollCallData, Line 0
Cannot assign a default value to a local variable.
Msg 137, Level 15, State 2, Procedure apGetRollCallData, Line 79
Must declare the scalar variable "@StartRange".
Msg 137, Level 15, State 2, Procedure apGetRollCallData, Line 89
Must declare the scalar variable "@StartRange".
  


I had the following declarations in my procedure that were causing the issue.




DECLARE @StartRange DATETIME = @ViewDate
DECLARE @EndRange DATETIME = @ViewDate





Once I changed it back to the following, it worked just fine in SQL Server 2005.




DECLARE @StartRange DATETIME
SET @StartRange = @ViewDate
DECLARE @EndRange DATETIME
SET @EndRange = @ViewDate



From a .NET developers point of view, I like having the ability to set a default value for a local variable in TSQL just like I can do in my programming language of choice.


 


Very nice. Thanks Microsoft.

Friday, August 7, 2009

NAnt .NET Framework 4.0 Configuration

4/14/2010 - Updated for .NET 4.0 RTM and feedback from comments.

For anyone who is using NAnt to build their solutions/projects and is also testing out Visual Studio 2010/.NET Framework 4.0 Beta 1, I have included below the .NET 4.0 Framework entry that I added to my NAnt.exe.config file and have been using to successfully compile my projects.

<framework
name="net-4.0"
family="net"
version="4.0"
vendor="MIcrosoft"
description="Microsoft .NET Framework 4.0"
sdkdirectory="${path::combine(sdkInstallRoot, 'bin')}"
frameworkdirectory="${path::combine(installRoot, 'v4.0.30319')}"
frameworkassemblydirectory="${path::combine(installRoot, 'v4.0.30319')}"
clrversion="4.0.30319"
>
<runtime>
<probing-paths>
<directory name="lib/net/2.0" />
<directory name="lib/net/neutral" />
<directory name="lib/common/2.0" />
<directory name="lib/common/neutral" />
</probing-paths>
<modes>
<strict>
<environment>
<variable name="COMPLUS_VERSION" value="v4.0.30319" />
</environment>
</strict>
</modes>
</runtime>
<reference-assemblies basedir="${path::combine(installRoot, 'v4.0.30319')}">
<include name="Accessibility.dll" />
<include name="mscorlib.dll" />
<include name="Microsoft.Build.Engine.dll" />
<include name="Microsoft.Build.Framework.dll" />
<include name="Microsoft.Build.Utilities.dll" />
<include name="Microsoft.Vsa.dll" />
<include name="Microsoft.VisualBasic.dll" />
<include name="Microsoft.VisualBasic.Compatibility.dll" />
<include name="Microsoft.VisualBasic.Compatibility.Data.dll" />
<include name="System.Configuration.dll" />
<include name="System.Configuration.Install.dll" />
<include name="System.Data.dll" />
<include name="System.Data.OracleClient.dll" />
<include name="System.Data.SqlXml.dll" />
<include name="System.Deployment.dll" />
<include name="System.Design.dll" />
<include name="System.DirectoryServices.dll" />
<include name="System.dll" />
<include name="System.Drawing.Design.dll" />
<include name="System.Drawing.dll" />
<include name="System.EnterpriseServices.dll" />
<include name="System.Management.dll" />
<include name="System.Messaging.dll" />
<include name="System.Runtime.Remoting.dll" />
<include name="System.Runtime.Serialization.Formatters.Soap.dll" />
<include name="System.Security.dll" />
<include name="System.ServiceProcess.dll" />
<include name="System.Transactions.dll" />
<include name="System.Web.dll" />
<include name="System.Web.Mobile.dll" />
<include name="System.Web.RegularExpressions.dll" />
<include name="System.Web.Services.dll" />
<include name="System.Windows.Forms.dll" />
<include name="System.Xml.dll" />
</reference-assemblies>
<task-assemblies>
<!-- include MS.NET version-neutral assemblies -->
<include name="extensions/net/neutral/**/*.dll" />
<!-- include MS.NET 2.0 specific assemblies -->
<include name="extensions/net/2.0/**/*.dll" />
<!-- include MS.NET specific task assembly -->
<include name="NAnt.MSNetTasks.dll" />
<!-- include MS.NET specific test assembly -->
<include name="NAnt.MSNet.Tests.dll" />
<!-- include .NET 2.0 specific assemblies -->
<include name="extensions/common/2.0/**/*.dll" />
</task-assemblies>
<tool-paths>
<directory name="${path::combine(sdkInstallRoot, 'bin')}"
if="${property::exists('sdkInstallRoot')}" />
<directory name="${path::combine(installRoot, 'v2.0.50727')}" />
<directory name="${path::combine(installRoot, 'v3.0')}" />
<directory name="${path::combine(installRoot, 'v3.5')}" />
</tool-paths>
<project>
<readregistry
property="installRoot"
key="SOFTWARE\Microsoft\.NETFramework\InstallRoot"
hive="LocalMachine" />
<readregistry
property="sdkInstallRoot"
key="SOFTWARE\Microsoft\.NETFramework\sdkInstallRootv2.0"
hive="LocalMachine"
failonerror="false" />
</project>
<tasks>
<task name="csc">
<attribute name="supportsnowarnlist">true</attribute>
<attribute name="supportswarnaserrorlist">true</attribute>
<attribute name="supportskeycontainer">true</attribute>
<attribute name="supportskeyfile">true</attribute>
<attribute name="supportsdelaysign">true</attribute>
<attribute name="supportsplatform">true</attribute>
<attribute name="supportslangversion">true</attribute>
</task>
<task name="vbc">
<attribute name="supportsdocgeneration">true</attribute>
<attribute name="supportsnostdlib">true</attribute>
<attribute name="supportsnowarnlist">true</attribute>
<attribute name="supportskeycontainer">true</attribute>
<attribute name="supportskeyfile">true</attribute>
<attribute name="supportsdelaysign">true</attribute>
<attribute name="supportsplatform">true</attribute>
<attribute name="supportswarnaserrorlist">true</attribute>
</task>
<task name="jsc">
<attribute name="supportsplatform">true</attribute>
</task>
<task name="vjc">
<attribute name="supportsnowarnlist">true</attribute>
<attribute name="supportskeycontainer">true</attribute>
<attribute name="supportskeyfile">true</attribute>
<attribute name="supportsdelaysign">true</attribute>
</task>
<task name="resgen">
<attribute name="supportsassemblyreferences">true</attribute>
<attribute name="supportsexternalfilereferences">true</attribute>
</task>
<task name="delay-sign">
<attribute name="exename">sn</attribute>
</task>
<task name="license">
<attribute name="exename">lc</attribute>
<attribute name="supportsassemblyreferences">true</attribute>
</task>
</tasks>
</framework>

Again, keep in mind that is what has worked for me. Your mileage may vary. Hope this helps.

Friday, July 24, 2009

NBuilder – A must have testing tool

I have recently been using NBuilder by Gareth Down. In my opinion, this testing tool is an absolute must for your toolbox. In my current project, we are going through a good deal of effort to create and correctly populate our objects under test. We have built an extensive suite of test helper methods to produce the objects. Now, with very minimal effort (and much less code) I can create a new object. Here is the description of the tool from the website home page:

“Through a fluent, extensible interface, NBuilder allows you to rapidly create test data, automatically assigning values to properties and public fields that are of type of the built in .NET data types (e.g. ints and strings). NBuilder allows you to override for properties you are interested in using lambda expressions.”

The NBuilder website contains a lot of great examples of the flexibility and power of this tool. Also, be sure to check out the NBuilder page on google code for moer examples, the features and bugs list, etc.

Thanks for creating such a great tool Gareth!

Tuesday, July 21, 2009

Are you on the Dark Side?

When you write code and test cases are you on the dark side or light side of testing? Do you use brute force?

Read Jeff’s Atwood’s blog, Testing With “The Force” to find out more…

Improving jQuery Performance

Giulio Bai has a great list of 10 Ways to Instantly Improve Your jQuery Performance. I highly recommend checking this article out if you are using jQuery.

Wednesday, June 10, 2009

Improving jQuery Selector Performance

Dave Ward just posted the great article, 11 keystrokes that made my jQuery selector run 10x faster.

If you are using jQuery in your web application, I highly recommend that you read this article and learn how to ensure that your jQuery selectors are running as fast as possible. Dave also includes some good hard data on the JavaScript performance differences between the older browsers: IE 7 & FireFox 3.0 as compared to the newer generation browsers like IE 8, FireFox 3.4 and Google Chrome.