LINQ to SQL pitfalls: Nullable types

Nullable booleans and comparisons

Testing if a nullable boolean is true is quite simple in C#, there are many ways, sorted here in my preference order.

bool? nullableBool = true;
var option1 = nullableBool == true;
var option2 = nullableBool.Equals(true)
var option3 = nullableBool.HasValue && nullableBool.Value;
var option4 = nullableBool ?? false;

All options return true in this case, false for nullableBool = false; and also false for nullableBool = null;

However, when using this expressions is labmdas inside a LINQ to SQL projection they will behave differently! LINQ to SQL it is not smart enough to translate to T-SQL in a way that the current ANSI_NULLS setting does not affect the query result. To avoid NULL = 1 comparisons, don’t use option1 or option2 there!

Huh? Please elaborate

Consider a table in Microsoft SQL Server, with a nullable bit column, like this

CREATE TABLE [dbo].[Banana] (
 [Id] INT,
 [IsYellow] bit NULL,
)

I will not get into whether you should have bit NULL columns or not (you probably shouldn’t) but if you do, and you are using LINQ to SQL to query your RDBMS, your generated Banana entity will have an IsYellow property, of  bool? C#type. Makes sense!

The following simplified code, though a little bit pointless in this case, is a perfectly valid situation if you wanted to avoid a nullable in your DTO, or you are projecting a boolean for any other reason.

ctx.Bananas.Select(x => new 
                      { 
                          Id = x.Id,
                          IsYellow = x.IsYellow == true
                      });

… but it will generate the following ANSI_NULL OFF dependent T-SQL code:

SELECT [t0].[Id], 
    (CASE 
        WHEN [t0].[IsYellow] = @p0 THEN 1
        WHEN NOT ([t0].[IsYellow] = @p0) THEN 0
        ELSE NULL
     END) AS [IsYellow]
FROM [Banana] AS [t0]

If there are any rows with NULL IsYelow, this code will will generate an “InvalidOperationException: The null value cannot be assigned to a member with type System.Boolean which is a non-nullable value type.” This happens because the  CASE will fall through the ELSE clause for any NULL value, thus returning a NULL in the result set, unasignable to our regular non-nullable boolean.

Note that the condition [t0].[IsYellow] = @p0, where @p0 is true and [IsYellow] is NULL, is neither true nor false according to the SQL 92 standard, this is the behavior when  ANSI_NULLS are are set to ON, wich is the default and will be actually forced ON in next versions of the MS SQL Server.

The last option will work as expected. For example:

ctx.Bananas.Select(x => new 
                      { 
                          Id = x.Id,
                          IsYellow = x.IsYellow ?? false
                      });

Would generate a safer NULL checking T-SQL code, like:

SELECT [t0].[Id], COALESCE([t0].[IsYellow],@p0) AS [IsYellow]
FROM [Banana] AS [t0]

You may also want to read:

 

Posted in .net | Tagged , , | 3 Comments

Coding Dojos Are Great

In 2012 I had the chance to participate in around dozen Coding Dojos. A Coding Dojo is, according to the codingdojo.org website:

… a meeting where a bunch of coders get together to work on a programming challenge. They are there have fun and to engage in Deliberate Practice in order to improve their skills.

And it works. It’s an amazing way to learn and reinforce best practices, and to share.

If you have not yet, go search when is the next coding dojo in your community, or organize yours!
dojo4dojo1
dojo2

Not only individuals and interactions,
but also a community of professionals.

 

Posted in Idle | Tagged | Leave a comment

FluentAssertions

FluentAssertions is a set of .NET extension methods that allow you to more naturally specify the expected outcome of a TDD or BDD-style test. It is written by Dennis Doomen and Martin Opdam. For a quick overview, take a look at the documentation.

Fluent!

FluentAssertions allows us to convert something like this:

[Test]
public void ReturnsYellowForBananas()
{
    var service = new FruitColorService();
 
    var result = service.GetColorOf(new Banana());
 
    Assert.AreEqual(Color.Yellow, result);
}

Into something like this:

[Test]
public void ReturnsYellowForBananas()
{
    var service = new FruitColorService();
 
    var result = service.GetColorOf(new Banana());
 
    result.Should().Be(Color.Yellow);
}

Exception checking

It also allows for this kind of exception checking (here using the Microsoft.Visual.Studio. UnitTesting namespace instead of NUnit like in the previous examples):

[TestMethod()]
[ExpectedException(typeof(InvalidFruitException))]
public void ThrowsAnExceptionIfItIsNotAFruit()
{
    var service = new FruitColorService();
 
    var result = service.GetColorOf(new Tomato());
}

To become the following snippet. I preffer this way because it keeps the arrange, act, assert form:

[TestMethod()]
public void ThrowsAnExceptionIfItIsNotAFruit()
{
    var service = new FruitColorService();
 
    Action action = () => service.GetColorOf(new Tomato());
 
    action.ShouldThrow<InvalidFruitException>();
}

I preffer the FluentAssertions way, but note that NUnit also has it’s fluent API for this purpose, using Assert.That in this case. the last two lines would become:

TestDelegate test = () => service.GetColorOf(new Tomato());
 
Assert.That(test, Throws.Exception
      .TypeOf<InvalidFruitException>());

When something goes wrong

In contrast to the Microsoft TestTools.Assert, both FluentAssertions and NUnit try hard to make the error message as clear as possible, when a test fails you certainly want to know what is happening and not just that it broke plus a meaningless line number. This is true specially if you are not on the IDE where you can just click-and-go to the ofending test, but reading a report from your continuous integration server. For the second test in this post, FluentAssertions would print out something like:

Expected object to be Color [Yellow], but found Color [Green].

Much more

FluentAssertions has lots of usseful methods to work with DateTime, TimeSpan, Collections, String, etc. It became an essential tool in my everyday work, if you are into C#, give it a try!

Posted in .net, Testing | Tagged , , , | Leave a comment

Thanks Agile Testing Days 2012!

It’s been less than a week since I came back from Berlin/Postdam from the best conference I attended this year, the Agile Testing Days. I co-presented a talk there with my colleague and friend Carlos Blé [thanks Carlos for proposing me this collaboration, it's always a pleasure to work together!], our talk was: BDD with Javascript for Rich Internet Applications. We are very happy with the outcome of the talk, but most importantly I’m  very happy with the overall level of the conference, the speakers, attendees, and the organization.

Agile Testing Days Conference Badge

Nice badge to add to the collection of trophies (and yes, I did scramble the QR)

I’m also thankful to the people at Diaz & Hilterscheid who organized the event, Madeleine Griep! who we drove crazy with changes in the hotel reservation many times, Uwe Gelfert, José Díaz, and the @AgileTD team.

I had the chance to personally meet Lisa Crispin and Gojko Adzic on the speaker’s dinner and during the conference. Lisa is one of the authors of the book Agile Testing, we also had the honor of having her at the front row in our talk! It’s good to put faces to the books we read :-)

Test Lab Rats

The Test Lab

From the left: Iván Stepaniuk, James Lyndsay, Carlos Blé, Bart Knaack.

James Lyndsay and Bart Knaack where on the TestLab, an amazing corner of the conference, totally hands-on where developers and testers shared their skills. Being a developer, it was really interesting to understand how professional testers work, sit with them and pair-test an application from a black-box perspective.  We also spent some time testing LiveTeamApp, a team time management application developed using the BDD techniques for JavaScript we talked about in this conference.

It was a really intensive experience and there are still ideas and notes to go through, and lots of new people to stay in touch with.

The call for papers for the next year is about to start, I hope to be there in 2013!

You may also want to read:

Posted in Agile, JavaScript, Testing | Tagged , , | Leave a comment

LINQ to SQL and multiple aggregate columns

The following very simple T-SQL query will return the average value for all values in the Rating column:

SELECT AVG(Rating) AS AvgRating FROM CarRating;

Doing this in LINQ to SQL is quite trivial; The Average method returns the average from the numeric sequence:

 var avgRating = Ctx.CarRatings.Select(x => x.Rating).Average();

The problem:

In the following example, we select an additional aggregate to get the maximum value of the whole Rating column in addition to the average:

SELECT AVG(Rating) AS Average, MAX(Rating) AS Maximum FROM CarRating;

In this case however, writing a LINQ to SQL equivalent is not that easy, one option would be splitting the query in two LINQ sentences. This is the most readable way to express what we want (and I like that), but hits the database twice and in some circumstances, specially if your table is big, you may not be able to live with that.

var avgRating = Ctx.CarRatings.Select(x => x.Rating).Average();
var maxRating = Ctx.CarRatings.Select(x => x.Rating).Max();
// Voila

The hack:

I refused to believe that there is no -good- way to express this simple SQL sentence in LINQ to SQL without hitting the DB twice. The only solution I have found so far, and the intertubes seem to agree, is to use a group by clause in the sentence. You would say; group by what? Well… that’s exactly the problem, it does not really make any sense, but if you group by a constant (!)…

var ratings = Ctx.CarRatings
                 .GroupBy(uselessConstant => 0)
                 .Select(r => new
                    { 
                      Avg = r.Average(x => x.Rating),
                      Max = r.Max(x => x.Rating)
                    })
                 .FirstOrDefault();
// Voila (WTF!)

This works, but remember that good code is readable code, naming the .GroupBy() lambda with something horrible like uselessConstantThatAllowsSelectingTwo-AggregateColumnsWithoutHittingTheDbTwice, is better that breaking the WTF-o-meter in a code-review or future maintenance. A comment may also be opportune in this case, perhaps even a link to this post ;)

Any comments or thoughts are welcome! Specially if you have a better way to solve this.

Posted in .net | Tagged , , | Leave a comment