I would not recommend that you use the NHibernate "bag" mapping option for a many-to-many association, for example:

image

Never mind the strange domain, it is for a upcoming NHibernate presentation and I was too bored with the normal Order > OrderLines example domains.

The reason why using a bag for many-to-many is not recommended is because of the poor update behavior you get. If you were to load an entity (RebelEncounter in this case) that has a ShipsLost many-to-many association and just add another StarDestroyer to the ShipsLost collection like this:

image

This would be issued to the database:

many_to_many_using_bag

As you can see all the existing ships where deleted and then reinserted (along with the single new one you added). You can probably guess that this is far from ideal from a performance stand point. However it is easy to fix. First we have to change the mapping from bag to set:

image

NHibernate will use the HashedSet type from the Iese.Collection framework as the collection type when using the set mapping, that means that the type for the property can no longer be IList<StarDestroyer> since HashedSet does not implement that interface, however it does implement ICollection<T>. So we can change the code to something like this:

image

With this change NHibernate will now only insert the newly added entity:

image

Series Index

  • Part 1: Reusable controller actions & model inheritance
  • Part 2: Custom meta data provider (coming soon)

One of the great new features in ASP.NET MVC 2 is the template system. It is very similar to the template form helper system introduced in MvcContrib for MVC V1. For more information on the MVC template system read Brad Wilsons excellent series

This template system allows you to create convention based views and forms. The scenario that I have been working with the last couple of days is forms for reports. These forms are all very similar, that is they are all built around a couple of report filters/parameters built using dropdowns, checkboxes and datetime pickers.

My idea was that each report would only consist of a new report model and the most of the views, and controller actions could be reused.

Example:

public class ReportController : Controller
{
    public ViewResult ViewRequestForm()
    {
        return View("ViewForm", new RequestReportForm());
    }

    public ViewResult ViewOrderForm()
    {
        return View("ViewForm", new OrderReportForm());
    }

    [HttpPost]
    public ActionResult ViewReport(ReportForm form)
    {
        return View(form.GetReportParameters());
    }
}
The idea is to be able to reuse the same root view and the same action for all forms. The root view is only going look something like this:
<% Html.BeginForm("ViewReport", "Report"); %>

    <%=Html.EditorFor(x => x)  %>
    <input type="submit" value="submit" />

<% Html.EndForm(); %>

The EditorFor helper is going to start the MVC template engine. This template engine is first going to try to find a matching editor template for the report form model, since no specific template exists it is going to fallback to the default template for object, this template loops through all properties defined on the model and applies an editor for each property.

This is how the RequestReportForm and OrderReportForm model looks like:

public class RequestReportForm : ReportForm
{
    [DisplayName("Include canceled requests")]
    public bool IncludeCanceledRequests { get; set; }

    [DisplayName("Some parameter")]
    public string SomeParameter { get; set; }
    
    public override string GetReportParameters()
    {
        return "RequestFilter=" + IncludeCanceledRequests;
    }
}

public class OrderReportForm : ReportForm
{
    [DisplayName("Group by status")]
    public bool GroupByStatus { get; set; }

    [DisplayName("Some other paramater")]
    public string SomeOrderParameter { get; set; }

    public override string GetReportParameters()
    {
        return "something";
    }
}   

With the default templates built into MVC these models will be rendered like this:

RequestReportForm:

image

OrderReportForm:

image

If we would like to override these templates all we have to do is create our own partial view and name it string.ascx or bool.ascx and place it in a view folder named EditorTemplates, hopefully more on that in a later part in this blog series.

So sharing the same view for both of these report models seems to be very easy with the template system built into MVC 2 but how do we use the same controller action? We want to use the the controller action ViewReport that takes the base type ReportForm as a parameter. The standard DefaultModelBinder will not know which concrete class to bind to. The solution to this problem should be to create a custom model binder that will figure out which concrete form model to instantiate based on some field coming in the post data from the browser.

Example:
public class ReportFormModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var reportFormTypeName = bindingContext.ValueProvider.GetValue("ReportFormTypeName");

        var reportFormType = Type.GetType("MvcApplication1.Models.ReportForms." + reportFormTypeName.AttemptedValue);

        var model = bindingContext.ModelMetadata.Model;
        
        bindingContext.ModelMetadata = new ModelMetadata(ModelMetadataProviders.Current, 
                bindingContext.ModelMetadata.ContainerType,
                () => model, reportFormType, bindingContext.ModelMetadata.PropertyName);
        
        return base.BindModel(controllerContext, bindingContext);
    }
}

This custom model binder looks for a form data field "ReportFormTypeName". With this name it is possible to get the .NET Type (based on some namespace convention) and thereby create a new ModelMetadata object, now we can call the base implementation. All we need to do now is to add this ReportFormTypeName field as a hidden field to our form. Lets add it to the base class ReportForm, like this:

public abstract class ReportForm
{
    [HiddenInput(DisplayValue = false)]
    public string ReportFormTypeName
    {
        get { return this.GetType().Name; }
    }

    public abstract string GetReportParameters();

}

This is actually all we have to do to get the MVC template system to generate a hidden field named ReportFormTypeName that will contain the name of the concrete Type. Since both RequestReportForm and OrderReportForm inherit from ReportForm and since the default template for object will loop through all properties (including inherited properties) the hidden field will be included for all report forms.

So what have we accomplished? We can generate different report forms by only creating a new form model, the view rendering is shared and the controller action to generate the report is also shared. The controller action that handles the viewing of the report is in my case only responsible for concatenating all report parameters into a querystring to then pass to the report system, since this is so generic it can be handled in the same controller action for all report forms. I hope some of you understand what I am trying to show here, and I also hope to expand on the ideas in this post in later posts. Specifically how to make the report parameters more rich and how to control and override the layout using custom editor templates and custom metadata.

kick it on DotNetKicks.com

One of NHiberantes features that I haven’t seen mentioned in the documentation or in blogs concerns the the two methods on ISession SaveOrUpdateCopy and Merge.

Lets say we have an backend (i.e. application server) that has an operation called UpdateOrder.

image

The UpdateOrder message contains a complete order. The normal scenario here is that the backend translate the order contained in the message to a domain model that is then persisted to the database via NHibernate. The problem with an update scenario like this is that the order that is coming in from the client could have missing order lines. If you use the normal ISession SaveOrUpdate method the order line that was removed on the client and therefore missing in the UpdateOrder message will not be deleted in the database.

Why won’t the missing order line be deleted from the db? Well consider this normal update scenario:

image

Here the order line is removed on the instance that is already attached to an open NHiberante session. In this case SaveOrUpdate will work perfectly because NHiberante can track the removal of the order line.

Consider this case (that represents the client –> backend scenario I mentioned above)

image

Here we try to save a detached instance which means that NHibernate’s dirty tracking and tracking of collection removals will not work.

How do you solve this problem? One approach is to fetch the order from the db and do a manual merge of the changes.  The current system that I am working on has a data access layer that is using LinqToSql and there are many, many update scenarios as described above. The amount of code to manually merge and figure out what has happened with all relations (added / removed order lines for example) is quite substantial.

For the last month we have been bit by bit migrating the data access layer to NHibernate. First I thought that this issue of updating detached objects would be a problem that we still needed to solve manually but then I discovered SaveOrUpdateCopy and Merge. These two functions does exactly what the old DAL did manually, that is before the update it fetches the persisted object from the db and then merges all changes from the detached instance into the persisted instance automatically, including orphaned child deletions!

Ex:

image

In the above code I modify an order line and remove another. Both operations are on a detached object. Then using SaveOrUpdateCopy we get this:

image

NHibernate fetches the order (in one statement by joining in the order lines), then performs the merge, figures out that one order line is updated and one is removed and issues the correct database calls. Is it just me but isn’t this great??? This will literally save thousands of lines of code! 

The ISession.Merge function basically does the same (from what I can tell). I am not sure really what separates them, except that there is cascade option named “merge” that you can set on relations to control how cascades should be propagated during merge operations.

Here is the API doc for Merge:

Copy the state of the given object onto the persistent object with the same
identifier. If there is no persistent instance currently associated with
the session, it will be loaded. Return the persistent instance. If the
given instance is unsaved, save a copy of and return it as a newly persistent
instance. The given instance does not become associated with the session.
This operation cascades to associated instances if the association is mapped
with cascade="merge". The semantics of this method are defined by JSR-220.

I think SaveOrUpdateCopy is something that has exited in NHiberante for all time and Merge is something added in 2.1 (clearly something ported from the hibernate). Anyway I am very glad that NHibernate has this ability because writing and handling the merge operation manually is very boring code to write! 

One useful feature in WPF 4.0 is the ability to databind to dynamic (runtime generated) properties using the DynamicObject as a base class or implementing the IDynamicMetaObjectProvider interface. I am currently working on a WPF application and this ability to bind to runtime generated properties would have been very useful in a previous story we implemented two weeks ago.

The story concerned merging two object graphs and then visualizing what properties that were changed/conflicted in the UI (for example with a different color).

In order to not add “XXX_HasMergeChange” for every property in the presentation model we solved this by using a value converter and some WPF binding magic that some might call a HACK. The solution was only partial as it only worked in the Grid and not on everything else.

If we had WPF 4.0 we could have solved this like this:

image

In the above style trigger the data trigger is binding to a property that doesn’t exist on the presentation model. How does WPF then get the value for this property? By calling the TryGetMember method:

image

WPF will call the TryGetMember and that will check if the property ends with “_HasMergeChange”, if that is the case it will try to look up the property in the MergeChanges dictionary.

The above is just a simple proof of concept, if I would go forward with this I would have to figure out a more generic way to define the style and data trigger to be able to reuse the xaml style markup for example, but that shouldn’t be a big problem. I also tested property change notifications using the INotifyPropertyChanged interface and they work for dynamic properties as well.

To learn more about the new features in WPF 4.0 read ScottGu’s recent post.

Among the Linq extensions methods that came with .NET 3.5 is one called Except. This method takes two lists (first and second)

The MSDN docs say:

This method returns those elements in first that do not appear in second. It does not also return those elements in second that do not appear in first.

This appears to be a lie. Review the code below and guess the output:

image

The User object has overridden the Equals and GetHashCode methods which the Except method use to determine equality. Since there is only one object in list2 that is also “equal” to an object in list1 I would expect (granted the MSDN docs are correct) that list3 would contain three users with the id zero.

The actual result? list3 will only contain ONE user object (with id zero). When I debug I see that Equals is called to compare objects in list1 with each other.

Using reflector I can see why, Except is implemented using the internal class System.Linq.Set:

image

It starts by adding all items from list2 into the set class then for each item from list1 that can be added to the set it yield returns. This filters all items from list1 that are equal to an item in list2 BUT it also filters all items in list1 that are equal any other item in list1!

Maybe not such a common usage scenario, and I don’t recommend overriding Equals and GetHashCode in this manner. Anyway frustrated by this because I burnt an hour on debugging before figured out it that what was to blame. 

NHibernate has pretty good support for batching, something that can significantly increase performance when inserting or updating large number of objects.

Example:

nh_batching

In the above example you can see that the order lines are created in one statement. In a recent mail conversation with Patrik Löwendahl he asked for assistance in getting batching to work. The first thing to check is what id generator you are using, you cannot use native (sql identity) id generator and expect batching to work for inserts. The reason for this that for identity inserts NHibernate issues a "select SCOPE_IDENTITY()" statement after each insert statement to fetch the generated ID. If you want to use batching for inserts you need to use the guid or hilo id generator.

Another issue i came across was that batching does not work as you would hope for associations. For example if you want to save a thousands orders and each order has five order lines, this would result in six thousands calls if batching was disabled and two thousands calls with batching enabled. As you see in the screenshot above, batching is only done on the order lines and not for everything.

You can optimize further by using the stateless session. However inserting entities using nhibernate’s stateless session ignores associations. But by looping through all orders and calling session.Insert(order), and then doing a nested loop to do the same for all order lines you can insert all orders and order lines in just two calls to the database.

The problem Patrik had was very weird and confusing. To verify that batching was actually happening he used SQL Profiler, while I used NHProfiler. The weird thing is that they show a very different picture. NHProfiler shows order lines as being issued in one command while SQL Profiler shows them as separate RPC calls.

+

image

This result left me very confused. The NHProfiler result clearly indicates that batching is being used but SQL Profiler shows the same results as when batching is off. However when batching is enabled the performance is significantly better, what is going on here?? After some Googling on SQL Profiler and batching I found this comment on stackoverflow:

On MS SQL Server, SQL Profiler shows each insert statement seems to be on it's own. After reviewing your comment, I viewed a TCP Dump of the conversation and do see that it is batching multiple commands together. SQL Profiler shows each insert as a "RPC Completed" event which was confusing me. Thanks for your help.

I appears that batching IS being done but not like I thought it would be (for example a Batch Starting command in SQL Profiler). The difference, when batching is turned on, is that all the statements are sent to the database in one go without waiting to listen for a response. That explains the SQL Profiler result, however I still find the NHProfiler result puzzling as it indicates that the order lines are created using a single call to sp_executesql.

image

Ayende care to explain? :)

Some links on NHibernate batching:

image There is a new release of NHibernate available, download it now. It contains a host of great new features, like support for Dependency Injection for entities using an inversion of control container of your choosing. There is also a new ANTLR based HQL parser that has allowed for some HQL improvements, like the with clause.  The new ANTLR based HQL parser is also central to the forthcoming LINQ support and is the result of some great work by  Steve Strong and Fabio.

This release also includes the long sought after support for executable bulk queries. This is a feature that the java (Hibernate) version has had for some time and is now fully ported to NHibernate.

For a complete list of new features: link