Monday, November 19, 2012

NHibernate: One-to-One Mapping With Shared Key

Preface

A reader commented on a different NHibernate post, asking about how one might do some different mappings. This post describes one of those scenarios: One-to-One mappings with a shared key. In this case, the parent entity has a surrogate key. The child is using the same value as its primary key and the same field as the foreign key to the parent.

Code samples for this article are on Github.

The Database

The test project is setup to run against a SQL Server database rather than some in-memory or mocked instance. I've created a quick SQL script to setup the datbase tables. SQL Server 2008 R2 was used for this example. The Express edition should work equally as well. We will be working with two tables:


The UserDetail.UserId is the same value as User.Id. Both are primary keys. There is a one-to-one relationship between the Users table and the UserDetail table. The UserDetail table, you will note, does not have an independent field for the foreign key.

The User Object

The first entity is the User. The User is the parent object. It is defined as follows. The AddDetail method is used to associate the different entities with each other. For example, if we have a new User and a new UserDetail, we can pass the UserDetail into the User.AddDetail() method. This will ensure that the UserDetail is correctly setup as the child of the User.

    public class User
    {
        public virtual long Id { get; set; }
        public virtual string Name { get; set; }
        public virtual UserDetail Detail { get; set; }

        public virtual void AddDetail(UserDetail userDetail)
        {
            Detail = userDetail;
            Detail.AddUser(this);
        }
    }

The User object's mapping is pretty basic. It sets the identity column as being generated by the database. It also sets the one-to-one mapping for the detail.

    public class UserMap : ClassMapping<User>
    {
        public UserMap()
        {
            Table("Users");

            Id(user => user.Id, mapper => mapper.Generator(Generators.Identity));

            Property(user => user.Name);

            OneToOne(user => user.Detail,
                     mapper =>
                     {
                         mapper.ForeignKey("FK_User_Id");
                         mapper.Cascade(Cascade.All);
                     });
        }
    }

The UserDetail Object

Next up is the UserDetail. UserDetail is a child of User, having a one-to-one relationship with its parent. The UserDetail.AddUser() method performs a similar function to the User.AddDetail() method: it helps setup the association between the UserDetail object and a parent User object. The Equals() and GetHashCode() overrides are necessary to accommodate the way we'll be setting up the mapping.

    public class UserDetail
    {
        public virtual long UserId { get; set; }
        public virtual string DriversLicense { get; set; }
        public virtual bool IsDonor { get; set; }
        public virtual User ParentUser { get; set; }

        public virtual void AddUser(User user)
        {
            ParentUser = user;
            UserId = user.Id;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
                return false;

            if (ReferenceEquals(this, obj))
                return true;

            var a = obj as UserDetail;
            if (a == null)
                return false;

            return a.UserId == UserId;
        }

        public override int GetHashCode()
        {
            unchecked
            {
                var hash = 21;

                hash = hash*37 + UserId.GetHashCode();
                
                return hash;
            }
        }
    }

The UserDetail mapping is a little more involved. Identifier is setup as a composite ID. This allows us to use NHibernates mapper to select the column name and the foreign key value. It also imposes the requirement that we have created the Equals() and GetHashCode() overrides.

    public class UserDetailMap : ClassMapping<UserDetail>
    {
        public UserDetailMap()
        {
            Table("UserDetail");

            ComposedId(mapper => mapper.ManyToOne(o => o.ParentUser, x =>
                                                                     {
                                                                         x.Column("UserId");
                                                                         x.ForeignKey("FK_User_Id");
                                                                     }));

            Property(detail => detail.DriversLicense);
            Property(detail => detail.IsDonor);
        }
    }

Persisting The Entities

One common mistake made when using NHibernate to persist related entities is to not set the relevant properties. In this case, the UserDetail.ParentUser property must be set, so that NHibernate can get the value of the ID property. I then to use a setter method to ensure any values are correctly set. In this case, it's the UserDetail.AddUser() method.

The tests file in the example solution gives two examples for persisting the entities to the database. It highlights how to ensure the critical step which happens just after creating the detailToBeSaved object.

        [TestMethod]
        public void SavingAUserWithADetailObject()
        {
            var userToBeSaved = Builder<User>.CreateNew()
                .With(user1 => user1.Id = 0)
                .Build();
            var detailToBeSaved = Builder<UserDetail>.CreateNew().Build();
            // Don't forget the next line...
            userToBeSaved.AddDetail(detailToBeSaved);

            object save;

            using (var txn = session.BeginTransaction())
            {
                save = session.Save(userToBeSaved);
                txn.Commit();
            }

            var loadedUser = session.Get<User>(save);

            loadedUser.ShouldHave().AllPropertiesBut(user => user.Id).EqualTo(userToBeSaved);
            loadedUser.Detail.ShouldHave().AllProperties().EqualTo(detailToBeSaved);

            using (var txn = session.BeginTransaction())
            {
                session.Delete(loadedUser);
                txn.Commit();
            }
        }

A Common Problem

It's pretty common to forget to initialize the child object before persisting. In this case, the UserDetail cannot exist without its parent User. However, if we do not setup the properties on the UserDetail via the AddUser() method or some other means, NHibernate won't know how to associate things. This results in an exception like the following:
Test method Prabu.Tests.OneToOneTests.SavingAUserWithADetailObject threw exception: NHibernate.Exceptions.GenericADOException: could not execute batch command.[SQL: SQL not available] ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'UserId', table 'Prabu.dbo.UserDetail'; column does not allow nulls. INSERT fails. The statement has been terminated.
This happens because NHibernate has no way to figure out what it should be inserting in the UserDetail.UserId field. You can prove this by commenting out the lines of the AddUser() method, and running the test.

Summary

It really is easier and better to just have a surrogate key with which to work. NHibernate is flexible enough to accommodate times when the world isn't perfect. I hope this helped show how to get around one of those sticky situations.

Tuesday, August 7, 2012

FakeItEasy with Action/Action Arguments

Preface

I discovered I couldn't use my go-to mock framework, NSubstitute, when unit testing Silverlight applications. A quick Google scan lead me to FakeItEasy, so I thought I'd give it a try. It's pretty intuitive, and has a decent, fluent interface. Here are some examples from the FakeItEasy Wiki.

A.CallTo(() => foo.Bar()).MustHaveHappened();
A.CallTo(() => foo.Bar()).MustNotHaveHappened();
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.AtLeast.Once);
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.Never);
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.NoMoreThan.Times(4));
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.Exactly.Twice);

My Problem

One of the services in the application I've been working on passes a lot of callbacks as parameters. They take the form of Action, Action<T>, Action<T1, T2>, etc. Since I had to be able to test these things, I had to figure a way to invoke the callback in the test. Here's an example of what I was dealing with:

public interface IFoo
{
    void Bar(int number, Action<bool> callback);
}

The Solution

It turns out the solution was pretty simple. FakeItEasy has an extension method (.Invokes()) which can invoke other delegates. This made it possible to extract and invoke the Action callback.

Action Type

When testing something with a simple Action parameter:

public interface IFoo
{
    void Bar(Action callback);
}

FakeItEasy can be used to execute the action. This is done by using the Invokes() extension method. We grab the argument we want, cast it to an Action, then call the action.

var foo = A.Fake<IFoo>();
A.CallTo(() => foo.Bar(A<Action>.Ignored))
               .Invokes(call =>
               {
                   var action = ((Action)call.Arguments.First());
                   action();
               }
         );

Action<T> Type

It's equally easy to handle actions that have one or more parameters. Below is an interface with a method that has two arguments. The Action<bool> callback is the one we want to grab.

public interface IFoo
{
    void Bar(string name, Action<bool> callback);
}

The solution is very close to the previous one. The Invokes() extension method is again used to access the call's arguments. Since the Action<bool> callback is the second argument of the method, the Linq First() expression is dropped in favor of the array. That argument is then cast and called.

var foo = A.Fake<IFoo>();

A.CallTo(() => foo.Bar(A<Action<bool>>.Ignored))
         .Invokes(call =>
         {
             var action = ((Action<bool>)call.Arguments[2]);
             action(true);
         });

Summary

I'm using FakeItEasy more often lately, because it can be used in more project types. Its interface is fluent and intuitive. I hope the example I gave will help others who are starting to check it out.

Thursday, August 2, 2012

Dapper-dot-net, DapperWrapper, and NSubstitute

Preface

Pretty much anyone who knows me will tell you that I'm all about test driven development. It gives you a safety net to refactor code. Unit tests also act as accurate documentation for what tested code does and how it does it. Lately I've been messing with Dapper-dot-net. Since I wanted to use Dapper in one of my recent projects, I had to know how to test its use. This is an example of how to unit test a class encapsulating a database query with Dapper and some other tools.

In this example, I will be using these tools:
Getting Started

The solution contains two projects: the class library and the unit test library. All the dependencies, save one, were added using NuGet. System.Data had to be added manually. The image below shows the solution layout.

Screen shot of the solution highlighting the dependencies.


We'll be querying a database which has a table of orders. The entity which represents an entry in the database is the Order class. This is a simple DTO, made to hold the data stored in the table:

    public class Order
    {
        public int OrderId { get; set; }
        public int CustomerId { get; set; }
        public int ShipperId { get;set; }
    }

The First Test

The first test will check the class is returning the expected data:

    public static class GetOrdersByCustomerIdTests
    {
        public class GetOrdersByCustomerIdContext : ContextSpecification
        {
            protected GetOrdersByCustomerId Sut;
            protected IDbExecutor DbExecutor;

            protected override void Context()
            {
                base.Context();

                DbExecutor = Substitute.For<IDbExecutor>();
                Sut = new GetOrdersByCustomerId();
            }
        }

        [TestClass]
        public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
        {
            private IEnumerable<Order> result;
            private List<Order> expectedResults;

            protected override void Context()
            {
                base.Context();

                expectedResults = Builder<Order>.CreateListOfSize(5)
                    .All().With(order => order.CustomerId = 1)
                    .Build()
                    .ToList();

                DbExecutor.Query<Order>(Arg.Any<string>(), Arg.Any<object>())
                    .Returns(expectedResults);
            }

            protected override void BecauseOf()
            {
                result = Sut.Execute(DbExecutor);
            }

            [TestMethod]
            public void ItShouldReturnTheOrders()
            {
                result.Should().BeEquivalentTo(expectedResults);
            }
        }
    }

There are a few things going on in this test class. DapperWrapper is giving us a means to test the query. Fluent Assertions is giving a nice, readable assertion. NSubstitute is being used to create a mock IDbExecutor. NBuilder is making some test data to be returned by our mock.

To make the test pass, we need to create the following class:

    public class GetOrdersByCustomerId
    {
        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>("", new object()); return query;
        }
    }

Adding the Query to the Test

As you can see, it's pretty simple. The next step is to ensure that the correct query is passed to the database. Since my testing is more BDD, I'm going to modify the Context() method. The Context() method represents the 'Given' of the Given-When-Then set.

 DbExecutor.Query<Order>("select OrderId, CustomerId, ShipperId from Orders where CustomerId=@CustomerId", Arg.Any<object>()).Returns(expectedResults);

This sets the mock to only return the list when the query string matches our expectations. The second parameter, Arg.Any<object>(), sets the mock to match against any object passed into the method.

    public class GetOrdersByCustomerId
    {
        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>("select OrderId, CustomerId, ShipperId from Orders where CustomerId=@CustomerId",                new object());
            
            return query;
        }
    }

Updating the class ensures the test will pass. The query won't really work though, because we're not passing in any parameters. If we were to actually try to use this class, it would throw an exception. So, now we'll start adding parameters to the query.

The First Parameter

With Dapper and DapperWrapper it's possible to simply add the parameter to the Query<T> extension method. The expectation is placed on the mock, and everything works. Here's the test class:

 [TestClass]
 public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
 {
    private IEnumerable<Order> result;
    private List<Order> expectedResults;
    private const int SampleCustomerId = 42;

    protected override void Context()
    {
         base.Context();

         expectedResults = Builder<Order>.CreateListOfSize(5)
            .All().With(order => order.CustomerId = 1)
            .Build()
            .ToList();

         DbExecutor.Query<Order>("select * from Orders where CustomerId=@CustomerId", SampleCustomerId)
            .Returns(expectedResults);
    }

    protected override void BecauseOf()
    {
         Sut.CustomerId = SampleCustomerId;
         result = Sut.Execute(DbExecutor);
    }

    [TestMethod]
    public void ItShouldReturnTheOrders()
    {
         result.Should().BeEquivalentTo(expectedResults);
    }
 }

And the query class:

    public class GetOrdersByCustomerId
    {
        public int CustomerId { get; set; }

        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>("select * from Orders where CustomerId=@CustomerId",
                CustomerId);
         
            return query;
        }
    }

More Than One Parameter

You might notice the second parameter of the Query<T> method is an object. This lets us pass in the parameters using an anonymous object. Pretty spiffy:

    public class GetOrdersByCustomerId
    {
        public int CustomerId { get; set; }
        public int ShipperId { get; set; }

        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>(
                "select OrderId, CustomerId, ShipperId from Orders where CustomerId=@CustomerId and ShipperId=@ShipperId",
                new { CustomerId, ShipperId });

            return query;
        }
    }

However, the test for the class is not as clean as you might expect. When I first started, I thought the following might work:
    [TestClass]
    public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
    {
        private IEnumerable<Order> result;
        private List<Order> expectedResults;
        private const int SampleCustomerId = 42;
        private const int SampleShipperId = 31;

        protected override void Context()
        {
            base.Context();

            expectedResults = Builder<Order>.CreateListOfSize(5)
                .All().With(order => order.CustomerId = 1)
                .Build()
                .ToList();

            var foo = new { CustomerId = SampleCustomerId, ShipperId = SampleShipperId };
            DbExecutor.Query<Order>("select * from Orders where CustomerId=@CustomerId", foo)
                .Returns(expectedResults);
        }

        protected override void BecauseOf()
        {
            Sut.CustomerId = SampleCustomerId;
            Sut.ShipperId = SampleShipperId;
            result = Sut.Execute(DbExecutor);
        }

        [TestMethod]
        public void ItShouldReturnTheOrders()
        {
            result.Should().BeEquivalentTo(expectedResults);
        }
    }


Unfortunately, this will still fail. NSubstitute fails to match the anonymous type. To get around this, we have to use the Arg.Do<object>() method with a lambda to snag the argument. This argument is assigned to a dynamic type, parameters. A little duck typing allows assertions against the values. The updated test looks like this:


    [TestClass]
    public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
    {
        private IEnumerable<Order> result;
        private List<Order> expectedResults;
        private const int SampleCustomerId = 42;
        private const int SampleShipperId = 31;
        private dynamic parameters;

        protected override void Context()
        {
            base.Context();

            expectedResults = Builder<Order>.CreateListOfSize(5)
                .All().With(order => order.CustomerId = 1)
                .Build()
                .ToList();

            DbExecutor.Query<Order>("select * from Orders where CustomerId=@CustomerId and ShipperId=@ShipperId",
                                    Arg.Do<object>(o => { parameters = o; }))
                .Returns(expectedResults);
        }

        protected override void BecauseOf()
        {
            Sut.CustomerId = SampleCustomerId;
            Sut.ShipperId = SampleShipperId;
            result = Sut.Execute(DbExecutor);
        }

        [TestMethod]
        public void ItShouldReturnTheOrders()
        {
            result.Should().BeEquivalentTo(expectedResults);
        }

        [TestMethod]
        public void ItShouldUseTheCorrectParameters()
        {
            ((int) parameters.CustomerId).Should().Be(SampleCustomerId);
            ((int) parameters.ShipperId).Should().Be(SampleShipperId);
        }
    }

While the test is correct, it was still failing. It was throwing an RuntimebinderException:

Test method DapperExample.UnitTests.GetOrdersByCustomerIdTests+WhenThereAreOrdersToReturn.ItShouldUseTheCorrectParameters threw exception:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'CustomerId'

It turns out that anonymous types are internal. The test assembly simply didn't have access to the properties of the anonymous type. The solution was pretty simple: expose the internal types to the unit test project. This is done by adding the following line to the AssemblyInfo.cs file:
[assembly: InternalsVisibleTo("DapperExample.UnitTests")]

Epilogue

Dapper is a nifty OR/M with a lot of features. DapperWrapper provides a simple way to do unit tests with projects using Dapper. Using the two, along with a few simple techniques, provides a means of writing good test which will document the code for posterity.

Tuesday, June 5, 2012

RabbitMQ: Node Names on Windows (Gotcha)

Though this is stated in the clustering guide, I managed to miss it:
The node name of a RabbitMQ broker started from the rabbitmq-server shell script is rabbit@shorthostname, where the short node name is lower-case (as in rabbit@rabbit1, above). If you use the rabbitmq-server.bat batch file on Windows, the short node name is upper-case (as inrabbit@RABBIT1). When you type node names, case matters, and these strings must match exactly.
Note the remote server name is in upper case for the first request, but in lower case for the second:


Tuesday, April 24, 2012

IoC: Windsor TypedFactoryFacility and Generics

Preface

Castle.Windsor is a powerful IoC framework. Since being cajoled into using it by a co-worker, I've come to really like it's features. Today I'm making a brain dump of something cool the TypedFactoryFacility can do. For those that don't know, this facility provides, "... automatically generated abstract factories..."

The Problem

I was creating a service host which exposed a few endpoints. These in turn called the business specific functionality. The service class already had four or five business specific methods on it. That's a lot of dependencies to put in a constructor.

    public class DrinkServiceWithoutFactory : IDrinkService
    {
        private readonly Fridge fridge;
        private readonly Machine machine;

        public DrinkServiceWithoutFactory(Fridge fridge, Machine machine)
        {
            this.fridge = fridge;
            this.machine = machine;
        }

        public IList<Can> GetCans()
        {
            return fridge.Dispense();
        }

        public IList<Bottle> GetBottles()
        {
            return machine.Dispense();
        }
    }

    public class Fridge : IDispenser<Can>
    {
        public IList<Can> Dispense()
        {
            Console.WriteLine("Creating 1 Can...");

            return new List<Can>
                   {
                       default(Can)
                   };
        }
    }

    public class Machine : IDispenser<Bottle>
    {
        public IList<Bottle> Dispense()
        {
            Console.WriteLine("Creating 2 bottles...");

            return new List<Bottle>
                   {
                       default(Bottle),
                       default(Bottle)
                   };
        }
    }

The Solution

An abstract factory was used to create the business-specific objects on demand, reducing the number of dependencies being injected into the constructor. the TypedFactoryFacility provides a handy means of creating delegate- or interface- based abstract factories automagically. What's not illustrated on the Castle documents site is that it can also create factories with generic methods.

The interface-based factory docs page explains how to create and use a factory interface. It doesn't really mention that the create method can also contain a generic. Below is an example of one that does.

    public interface IDispenserFactory
    {
        T Create<T>()
            where T : IDispenser;

        void Release(IDispenser iDispenser);
    }


This depends on two other definitions:

    public interface IDispenser
    {
        
    }

    public interface IDispenser<T> : IDispenser
        where T : class 
    {
        IList<T> Dispense();
    }
Now that we have the factory setup, we can register the components:
    public class Program
    {
        static void Main()
        {
            try
            {
                var container = new WindsorContainer();

                container.AddFacility<TypedFactoryFacility>();

                container.Register(
                    Component.For<Demo>(),
                    Component.For<Machine>(),
                    Component.For<Fridge>(),
                    Component.For<IDispenserFactory>().AsFactory(),
                    Component.For<IDrinkService>().ImplementedBy<DrinkService>()
                    );

                var demo = container.Resolve<Demo>();
                demo.Run();
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);
            }   
            finally
            {
                Console.ReadKey();
            }
        }
    }
    public class Demo
    {
        private readonly IDrinkService service;

        public Demo(IDrinkService service)
        {
            this.service = service;
        }

        public void Run()
        {
            var bottles = service.GetBottles();
            Console.WriteLine("Bottles created: {0}", bottles.Count);

            var cans = service.GetCans();
            Console.WriteLine("Cans created: {0}", cans.Count);
        } 
    }

We can then change the service implementation to use the abstract factory:

    public class DrinkService : IDrinkService
    {
        private readonly IDispenserFactory factory;

        public DrinkService(IDispenserFactory factory)
        {
            this.factory = factory;
        }

        public IList<Can> GetCans()
        {
            var fridge = factory.Create<Fridge>();
            return fridge.Dispense();
        }

        public IList<Bottle> GetBottles()
        {
            var machine = factory.Create<Machine>();
            return machine.Dispense();
        }
    }

The results (quick and dirty):

Console output of the different classes.
The results...

Summary

This was just a quick brain dump to illustrate that the TypedFactoryFacility can do generics as well.

Tuesday, March 6, 2012

TDD: NSubstitute, CQRS, and abstract classes...

Preface

I'm a fan of CQRS. It's a great way to separate concerns when dealing with data. In fact, I'm a pretty big fan of the command pattern as a whole. One of the big issues I've faced with using this pattern is unit testing the queries. (Note: this is a pretty contrived example, but it should get the idea across.) Sample code can be found on Github.

The Problem

I want to implement some kind of cache object, and I want to use CQRS in fetching the entities from the database. To top it off, I want to unit test the cache. Here's a look at the cache (and yes, I know it's not really caching anything):

    public class ReportCache
    {
        private readonly ISession session;
        private readonly GetReportByDateAndType getReportByDateAndType;

        public ReportCache(ISession session, GetReportByDateAndType getReportByDateAndType)
        {
            this.session = session;
            this.getReportByDateAndType = getReportByDateAndType;
        }

        public Report GetReportByDateAndType(DateTime reportDate, ReportType reportType)
        {
            getReportByDateAndType.ReportDate = reportDate;
            getReportByDateAndType.ReportType = reportType;
            var reports = getReportByDateAndType.Execute(session);

            return reports.First();
        }
    }

The Solution

The hurdle is how to mock out the query object. I've always tried to implement some kind of interface with varying levels of success. Following that approach made it difficult to use/inject the query into whatever object was using it.

I was usually left with an interface supplied in the constructor which had to be downcast to allow access to the properties. Another option would be to supply a factory object, which could create the appropriate query when necessary. The former being a Liskov Substitution Principle violation. The latter adding unnecessary complexity.

One day, I realized I could use abstract classes, and life became a little easier. Let's say we start with the query itself:

    public class GetReportByDateAndType : QueryBase
    {
        public DateTime ReportDate { get; set; }
        public ReportType ReportType { get; set; }

        public override IQueryable<Report> Execute(ISession session)
        {
            return session.Query<Report>()
                .Where(report => report.ReportDate == ReportDate && report.Type == ReportType);
        }
    }

You'll notice that the queries inherit from a base class. This class is an abstract, and enforces that the Execute() method can be overridden. I'm using this similar to an interface. It's a means to define what the queries will look like:

    public abstract class QueryBase
    {
        public abstract IQueryable<Report> Execute(ISession session);
    }

Doing a unit test with this setup, becomes a matter of simply mocking the query. This can be done with a framework or a hand-rolled mock. The following is an example using NSubstitute:

    public static class ReportCacheTests
    {
        public class ReportCacheSpecs : ContextSpecification
        {
            protected ReportCache Sut;
            protected GetReportByDateAndType TestQuery;
            protected ISession TestSession;

            protected override void Context()
            {
                TestSession = Substitute.For<ISession>();
                TestQuery = Substitute.For<GetReportByDateAndType>();
                Sut = new ReportCache(TestSession, TestQuery);
            }
        }

        [TestClass]
        public class MockWithNSubstitute : ReportCacheSpecs
        {
            private Report expectedReport;
            private Report result;
            private DateTime testDate;
            private ReportType testReportType;

            protected override void Context()
            {
                base.Context();

                testDate = new DateTime(2012, 01, 02);
                testReportType = ReportType.Cost;

                expectedReport = new Report
                                     {
                                         ReportId = 42L,
                                     };
                TestQuery.Execute(TestSession)
                    .Returns(new List<Report> { expectedReport }.AsQueryable());
            }

            protected override void BecauseOf()
            {
                result = Sut.GetReportByDateAndType(testDate, testReportType);
            }

            [TestMethod]
            public void TheCacheShouldReturnTheFirstReport()
            {
                result.Should().Be(expectedReport);
            }

            [TestMethod]
            public void TheCorrectParametersShouldBeSetOnTheQuery()
            {
                TestQuery.ReportDate.Should().Be(testDate);
                TestQuery.ReportType.Should().Be(testReportType);
            }
        }
    }

I've posted an example to Github. You'll notice the example also shows how to extend the functionality of the query without using inheritance. I plan on writing a blog about this at a later date. An added bonus is any IoC container can be used to supply the query, so there's no need for a factory.

Thursday, February 2, 2012

NHibernate Samples: Row Versioning with SQL Server Timestamp

Preface

I've recently switched from using FluentNHibernate to NHibernate. The decision was made to reduce the number of dependencies required by a solution. Since NHibernate (3.2+) now includes a means of mapping entities to database tables, I just didn't need to use FNH. The big problem I've run into as a result of the switch is the lack of samples on the 'net. Since I can't do my normal R&D (rip-off and duplicate), I've had to resort to actual learning. These articles are intended as a means to provide me with a way to consolidate what I've copied/learned. They should also serve as a way to give other people a handy reference.

I've also created a solution on github to host the code. Fee free to download it, copy it, recycle it, or ignore it.

The Problem

This post is related to a question on stackoverflow.com, NHibernate 3.2 By Code ClassMapping for Version Property. SQL Server has an 8-byte incremental number, the timestamp, which can be used for row versioning. However, it's not immediately obvious how to map the column in the database to an entity.

Note: DateTime is bad for Timestamp

It's worth noting that a DateTime does not have sufficient resolution to be used as a timestamp. See this stackoverflow question, and this msdn article.

The Solution

Since a SQL timestamp is equivalent to the C# byte[] type, NHibernate needs help making the translation. The solution is using a custom IUserVersionType. Conveniently, there is already an implementation buried within the NHibernate source code: the BinaryTimestamp. Using this class, it's possible to map an entity's property to the table's column.

The custom type

This type tells NHibernate how to handle the conversion between the SQL timestamp type and C# byte[] type.

    public class BinaryTimestamp : IUserVersionType
    {
        #region IUserVersionType Members

        public object Next(object current, ISessionImplementor session)
        {
            return current;
        }

        public object Seed(ISessionImplementor session)
        {
            return new byte[8];
        }

        public object Assemble(object cached, object owner)
        {
            return DeepCopy(cached);
        }

        public object DeepCopy(object value)
        {
            return value;
        }

        public object Disassemble(object value)
        {
            return DeepCopy(value);
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public bool IsMutable
        {
            get { return false; }
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            return rs.GetValue(rs.GetOrdinal(names[0]));
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            NHibernateUtil.Binary.NullSafeSet(cmd, value, index);
        }

        public object Replace(object original, object target, object owner)
        {
            return original;
        }

        public System.Type ReturnedType
        {
            get { return typeof(byte[]); }
        }

        public SqlType[] SqlTypes
        {
            get { return new[] { new SqlType(DbType.Binary, 8) }; }
        }

        public int Compare(object x, object y)
        {
            var xbytes = (byte[])x;
            var ybytes = (byte[])y;
            return CompareValues(xbytes, ybytes);
        }

        bool IUserType.Equals(object x, object y)
        {
            return (x == y);
        }

        #endregion

        private static int CompareValues(byte[] x, byte[] y)
        {
            if (x.Length < y.Length)
            {
                return -1;
            }
            if (x.Length > y.Length)
            {
                return 1;
            }
            for (int i = 0; i < x.Length; i++)
            {
                if (x[i] < y[i])
                {
                    return -1;
                }
                if (x[i] > y[i])
                {
                    return 1;
                }
            }
            return 0;
        }

        public static bool Equals(byte[] x, byte[] y)
        {
            return CompareValues(x, y) == 0;
        }
    }

An example table definition


This is an example table. Note the name of the timestamp column. Our entity will use a differently named property to store the value in memory.
create table Orders
(
 OrderId bigint primary key identity
 ,Comments varchar(max) not null default ''
 ,DatePlaced datetime not null default getdate()
 ,LastModified timestamp not null
)

An example model/entity

    public class Order
    {
        public virtual long OrderId { get; set; }
        public virtual string Comments { get; set; }
        public virtual DateTime DatePlaced { get; set; }
        public virtual byte[] Version { get; set; }

        public override string ToString()
        {
            return string.Format("Order ({0}) - {1}", OrderId, DatePlaced);
        }
    }

An example of the mapping

The version statement contains the instructions for NHibernate. mapper.Generated(VersionGeneration.Always) tells NHibernate that SQL Server will handle generation of the value. mapper.Column("LastModified") tells NHibernate that the name of the column is different from the name of the property. mapper.Type<BinaryTimestamp>() tells NHibernate what class to use in converting the sql timestamp type to a C# byte[] and vice versa.

    public class OrderMap : ClassMapping<Order>
    {
        public OrderMap()
        {
            Table(DatabaseTable.Orders);

            Id(order => order.OrderId, mapper => mapper.Generator(Generators.Identity));
            
            Property(order => order.Comments);
            Property(order => order.DatePlaced);
            
            Version(order => order.Version, mapper =>
                          {
                              mapper.Generated(VersionGeneration.Always);
                              mapper.Column("LastModified");
                              mapper.Type<BinaryTimestamp>();
                          });
        }
    }