title: LINQ-NHibernate - Selecting only a few fields (including a Collection) for a complex object
body: <p>I'm using Fluent NHibernate in one of my projects (and ASP.NET MVC application), with LINQ to query to data (using the LINQ to NHibernate libraries).</p>
  
  <p>The objet names are changed to protect the innocent.</p>
  
  <p>Let's say I have the following classes Foo, Bar, Baz, and their appropriate tables in the database (MySQL).</p>
  
  <p>Foo has a many-to-many relationship with both Bar (table "FooBar") and Baz (table "FooBaz"), defined in the Fluent mappings. As such, the class interface is defined as follows:</p>
  
  <pre><code>public class Foo {
      public virtual int id { get; set; }
      public virtual string name { get; set; }
      public virtual string email { get; set; }
      public virtual IList&lt;Bar&gt; bars { get; set; }
      public virtual IList&lt;Baz&gt; bazes { get; set; }
  }
  </code></pre>
  
  <p>This is a pretty standard class. We can see that a Foo object will have a list of bars and bazes.</p>
  
  <p>The problem comes when trying to do a LINQ query.</p>
  
  <p>If I do a simple query like this, it works fine (the where clause is unimportant) :</p>
  
  <pre><code>var foos = from foo in session.Linq&lt;Foo&gt;()
             where email.equals("foo@bar.com")
             select foo;
  
  IList&lt;Foo&gt; listFoos = foos.ToList();
  </code></pre>
  
  <p>This will return a list of Foos, with all the fields populated (id, name, email, bars, bazes). log4net shows that NHibernate performs separate queries for the collections.</p>
  
  <p>The problem arises when I want to load only some fields. For example, I might want to load only the bars in the query, but not the bazes.</p>
  
  <p>This query compiles, but produces an error at runtime:</p>
  
  <pre><code>var foos = from foo in session.Linq&lt;Foo&gt;()
             where email.equals("foo@bar.com")
             select new Foo() 
             {
                 id = foo.id,
                 name = foo.name,
                 email = foo.email,
                 bars = foo.bars
             };
  
  IList&lt;Foo&gt; listFoos = foos.ToList();
  </code></pre>
  
  <p>The error I get is something along the lines of an array index out of bounds exception. The stack trace shows some methods names relating the collection handling on LINQ-NHibernate's side, but nothing else. The query reported by log4net shows no sign of a query on bars, which means than an error was caught before it had the time to perform the query to select the bars.</p>
  
  <p>Did anyone else had this kind of problem before? How did you solve it? I don't want to have to select all the objects everytime I open a web page in my application!</p>
  
  <p>Thank you!</p>
  
  <p><strong>Edit: here is the stacktrace, as requested.</strong></p>
  
  <pre><code>System.IndexOutOfRangeException: L'index se trouve en dehors des limites du tableau. (read: "Index is out of bounds for the array.")
  
  [IndexOutOfRangeException: L'index se trouve en dehors des limites du tableau.]
     NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.InvokeMemberInitExpression(MemberInitExpression expression, Object[] args, Int32&amp; argumentCount) +404
     NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.TransformTuple(Object[] tuple, String[] aliases) +150
  
  [QueryException: could not instantiate: Foo]
     NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.TransformTuple(Object[] tuple, String[] aliases) +265
     NHibernate.Loader.Criteria.CriteriaLoader.GetResultColumnOrRow(Object[] row, IResultTransformer resultTransformer, IDataReader rs, ISessionImplementor session) +171
     NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) +330
     NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +704
     NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +70
     NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +111
     NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) +18
     NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) +79
     NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) +407
     NHibernate.Impl.CriteriaImpl.List(IList results) +41
     NHibernate.Impl.CriteriaImpl.List() +35
     NHibernate.Linq.&lt;GetEnumerator&gt;d__0.MoveNext() +71
     System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +7665172
     System.Linq.Enumerable.ToList(IEnumerable`1 source) +61
     FooRepository.List(Int32 count) in C:\...\FooRepository.cs:38
     FooController.List() in C:\...\FooController.cs:30
     lambda_method(ExecutionScope , ControllerBase , Object[] ) +39
     System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
     System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +178
     System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +24
     System.Web.Mvc.&lt;&gt;c__DisplayClassa.&lt;InvokeActionMethodWithFilters&gt;b__7() +52
     System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +254
     System.Web.Mvc.&lt;&gt;c__DisplayClassc.&lt;InvokeActionMethodWithFilters&gt;b__9() +19
     System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +192
     System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +399
     System.Web.Mvc.Controller.ExecuteCore() +126
     System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27
     System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
     System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +151
     System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57
     System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
     System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
     System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +75
  </code></pre>