Search code examples
sql-servernhibernatesql-server-mars

What effect does MARS have on NHibernate?


I'm comparing Entity Framework with NHibernate, and I'd like to know if when using SQL Server, what effect (if any) would enabling or disabling MARS support have on NHibernate?

MARS = Multiple Active Result Sets

The Entity Framwork documentation states the following:

When you call the Load method during a foreach (C#) or For Each (Visual Basic) enumeration, the Entity Framework tries to open a new data reader. This operation will fail unless you have enabled multiple active results sets by specifying multipleactiveresultsets=true in the connection string. For more information, see Using Multiple Active Result Sets (MARS) on MSDN. You can also load the result of the query into a List collection, which closes the data reader and enables you to enumerate over the collection to load referenced entities.

Does NHibernate has the same issue?

Additional information when connecting to SQL Azure


Solution

  • The issue you're referring to is linked to "server side cursors", and as far as I know of nHibernate this shouldn't be an issue, simply because it don't use them.
    If you're using LINQ to load objects in nHibernate, on the first access to the foreach enumeration, nHibernate load in memory the whole resultset of the query, and this way it can use the session's connection to load everything else. When using HQL query or Criteria, it will load the resultset when you call "List()" then it close the connection.

    Entity framework on the flip side, try to be smart and make use of server side cursors when scrolling a collection via a foreach enumeration, so the objectContext's connection is "busy" with the server side cursor until the foreach enumeration is ended. If MARS is not enabled, EF can't use the connection to load another resultset (you can still issue other statements such update, insert and delete) and thus it will give you an error like "There is already an open DataReader associated with this Command which must be closed first" or something similar.

    Hope this helps,
    Marco
    EDIT:
    After some research I've found that nHibernate could use MARS, but still in ver 3.2.0.4000 there's no driver for SqlServer that supports it. Of course in the SqlClientDriver is not supported (as it is inteded for Sql2000 that has no support for MARS) but even in the Sql2008ClientDriver the relevant property is set to false. Anyway this is something I'll post to the nHibernate team as soon as possible