LINQ-NHibernate - die Auswahl von nur wenigen Feldern (einschließlich Sammlung) für ein Komplexes Objekt

Ich bin mit Fluent NHibernate in einem meiner Projekte (und ASP.NET MVC-Anwendung), mit LINQ-Abfragen, um die Daten (unter Verwendung des LINQ to NHibernate Bibliotheken).

Den objet Namen geändert zum Schutz der unschuldigen.

Sagen wir, ich habe die folgenden Klassen Foo, Bar, Baz, und die entsprechenden Tabellen in der Datenbank (MySQL).

Foo hat eine viele-zu-viele-Beziehung mit sowohl Bar (Tabelle "FooBar") und Baz (Tabelle "FooBaz"), definiert in der Fluent-mappings. Als solche, die Klassen-Schnittstelle ist wie folgt definiert:

public class Foo {
    public virtual int id { get; set; }
    public virtual string name { get; set; }
    public virtual string email { get; set; }
    public virtual IList<Bar> bars { get; set; }
    public virtual IList<Baz> bazes { get; set; }
}

Dies ist ein ziemlich standard-Klasse. Wir können sehen, dass ein Foo-Objekt wird eine Liste von bars und bazes.

Das problem kommt, wenn Sie versuchen zu tun, eine LINQ-Abfrage.

Mache ich, wenn ich eine einfache Abfrage wie diese, funktioniert es einwandfrei (die where-Klausel ist unwichtig) :

var foos = from foo in session.Linq<Foo>()
           where email.equals("[email protected]")
           select foo;

IList<Foo> listFoos = foos.ToList();

Dieser gibt eine Liste von Foos, mit allen gefüllten Feldern (id, name, E-Mail, bars, bazes). log4net zeigt, dass NHibernate führt separate Abfragen für die Sammlungen.

Entsteht das problem, wenn ich laden will nur einige Felder. Ich könnte zum Beispiel möchten, laden Sie nur noch die bars in der Abfrage, aber nicht die bazes.

Diese Abfrage kompiliert wird, aber erzeugt einen Fehler zur Laufzeit:

var foos = from foo in session.Linq<Foo>()
           where email.equals("[email protected]")
           select new Foo() 
           {
               id = foo.id,
               name = foo.name,
               email = foo.email,
               bars = foo.bars
           };

IList<Foo> listFoos = foos.ToList();

Den Fehler den ich bekomme, ist etwas entlang der Linien von einem array-index out of bounds exception. Der stack-trace zeigt einige Methoden, Bezeichnungen die im Zusammenhang der Sammlung Handhabung von LINQ-NHibernate-Seite, aber sonst nichts. Die Abfrage berichtet von log4net zeigt keine Anzeichen einer Abfrage auf Balken, was bedeutet, dass ein Fehler abgefangen wurde, bevor es die Zeit zum ausführen der Abfrage wählen Sie die bars.

Hatte noch jemand diese Art von problem vor? Wie hast du es lösen? Ich will nicht zu haben, wählen Sie alle Objekte jedesmal, wenn ich öffnen Sie eine web-Seite in meiner Bewerbung!

Danke!

Edit: hier ist der stacktrace, wie gewünscht.

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& 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.<GetEnumerator>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.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7() +52
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +254
   System.Web.Mvc.<>c__DisplayClassc.<InvokeActionMethodWithFilters>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& completedSynchronously) +75
poste bitte die vollständige exception mit stack-trace

InformationsquelleAutor Guillaume Gervais | 2010-01-05

Schreibe einen Kommentar