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 aforeach
(C#) orFor 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 specifyingmultipleactiveresultsets=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
Multiple Active Result Sets (MARS) is a feature that works with SQL Server to allow the execution of multiple batches on a single connection. When MARS is enabled for use with SQL Server, each command object used adds a session to the connection.
You should enable MARS if you perform operations that require MARS, otherwise those will fail. Whether you or anyone else should write code that uses such operations is subjective.
Multiple Active Result Sets (MARS) is a feature that allows the execution of multiple batches on a single connection. In previous versions, only one batch could be executed at a time against a single connection. Executing multiple batches with MARS does not imply simultaneous execution of operations.
A batch or stored procedure which starts a manual or implicit transaction when MARS is enabled must complete the transaction before the batch exits. If it does not, SQL Server rolls back all changes made by the transaction when the batch finishes.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With