2012-04-11 11 views
3
fetch

Trotz Mapping Einrichtung Not.Nullable() und Not.LazyLoad()Nhibernate Erzeugen OUTER zum Verbinden mit einem

Aus irgendeinem Grunde zu sein, NH eine Tabelle zweimal beitritt, einmal mit einem INNER JOIN die WHERE, zu beruhigen und andererseits auf einem OUTER JOIN Wählen Sie die Daten aus.

Sicher, wie wir haben bereits die Daten verbunden sind, wäre es sinnvoll, nur die Join-Tabelle zu verwenden ...

SELECT 
    ...Tables.. 
from Tasks taskentity0_, 
outer Cases caseentity1_, 
outer Grades gradeentit2_, 
Cases caseentity5_ 
WHERE 
.... 

Meine LINQ-Abfrage für diese ist:

IQueryable<TaskEntity> tasks = TaskRepo.Find(
    t => t.DueDate <= DateTime.Now 
     && (t.TaskInitials == userInitials || (t.TaskInitials == "" || t.TaskInitials == null)) 
     && t.Team.GST.Any 
        (x => x.Initials == userInitials 
         && x.WorkType.WorkTypeCode == t.WorkType.WorkTypeCode 
         && x.Team.TeamCode == t.Team.TeamCode 
        ) 
     && (t.Case.CaseOnHold <= DateTime.Now || t.Case.CaseOnHold == null || (t.SingleTask == "M" || t.SingleTask == "m")) 
     && (t.Case.CaseMatter.StartsWith("0") || t.Case.CaseMatter.StartsWith("9")) 
       ).Fetch(t => t.Case,FetchProvider) 

Meine Referenz-Mapping:

 References(x => x.Case).Column("ta_c_ref").Not.Nullable(); 

Gedanken?

Wir verwenden das Repository-Muster und haben die Fetch-Erweiterungsmethode so implementiert, dass sie auf diese Weise funktioniert (also den FetchProvider übergeben).

Auch ist QueryOver<T> keine Option hier, da wir IQueryable s benötigen ..

ich verwende NH 3.1.

Für die Massen:

Wir haben nicht mehr die Fetch oder LINQ verwenden, zogen wir in HQL ...

/// <summary> 
    /// Interfaces for Fetch() statements 
    /// </summary> 

    public interface IFetchingProvider 
    { 
     IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector); 

     IFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector); 

     IFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector); 

     IFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector); 
    } 


public class NhFetchingProvider : IFetchingProvider 
    { 
     public IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector) 
     { 
      var fetch = EagerFetchingExtensionMethods.Fetch(query, relatedObjectSelector); 
      return new FetchRequest<TOriginating, TRelated>(fetch); 
     } 

     public IFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector) 
     { 
      var fecth = EagerFetchingExtensionMethods.FetchMany(query, relatedObjectSelector); 
      return new FetchRequest<TOriginating, TRelated>(fecth); 
     } 

     public IFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector) 
     { 
      var impl = query as FetchRequest<TQueried, TFetch>; 
      var fetch = EagerFetchingExtensionMethods.ThenFetch(impl.NhFetchRequest, relatedObjectSelector); 
      return new FetchRequest<TQueried, TRelated>(fetch); 
     } 

     public IFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector) 
     { 
      var impl = query as FetchRequest<TQueried, TFetch>; 
      var fetch = EagerFetchingExtensionMethods.ThenFetchMany(impl.NhFetchRequest, relatedObjectSelector); 
      return new FetchRequest<TQueried, TRelated>(fetch); 
     } 
} 

public static IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(this IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector, Func<IFetchingProvider> FetchingProvider) 
     { 
      return FetchingProvider().Fetch(query, relatedObjectSelector); 
     } 
+0

Das Repository-Muster beendet die Funktionalität von NHibernate. Meine Meinung und viele andere teilen den gleichen Gedanken. – CrazyCoderz

+0

Es wäre hilfreich, den Quellcode der Fetch-Erweiterung zu sehen. – Hoghweed

+0

Von der Geschichte aus aktualisiert - der Code ist jetzt fast ein Jahr alt und wird nicht benutzt. –

Antwort

0

Mit Innen mit Linq in NHibernate schließt sich noch nicht unterstützt. Weitere Informationen finden Sie hier: https://nhibernate.jira.com/browse/NH-2790

+0

Danke dafür - es zu JIRA hinzuzufügen, scheint über eine viel Verwendung, wie es zu meiner Amazon Wunschliste hinzufügen - aber hey ho, könnte es passieren! –

+1

@ Stuart.Sklininar traurig, aber wahr. – TedOnTheNet

0

Ich habe Unterstützung dafür hinzugefügt!

https://www.nuget.org/packages/NHibernate.Linq.InnerJoinFetch

Genießen Sie !!!

+0

Ist das Open Source? Könnten Sie verlinken - Github? So bieten wir Verbesserungen, Gabel etc ....? –

+2

Klicken Sie auf die Projektseite auf der Nuget-Seite oder klicken Sie hier https://github.com/eallegretta/nhibernate-linq-innerjoin-fetch – Paleta

Verwandte Themen