2014-01-13 4 views
6

Mit NHibernate 3.3.1.400 habe ich Probleme mit dem Ausdruck eines einfachen SQL-Statements mit dem Linq-Provider von NHibernate.Problem bei der Formulierung innerer Joins mit der NHibernate-Linq-Abfrage

Mein Domain-Modell sieht wie folgt aus:

public class Site 
{ 
    public virtual Guid Id {get; set;} 
    public virtual string Name {get; set;} 
} 

// a site has many filers 
public class Filer 
{ 
    public virtual Guid Id {get set;} 
    public virtual Site Site {get; set;} 
    public virtual string Name {get; set;} 
} 

// a filer has many filings 
public class Filing 
{ 
    public virtual Guid Id {get set;} 
    public virtual Filer Filer {get; set;} 
    public virtual DateTime FilingDate {get; set;} 
} 

//a filing has many items 
public class Item 
{ 
    public virtual Guid Id {get set;} 
    public virtual Filing Filing {get; set;} 
    public virtual DateTime Date {get; set;} 
    public virtual decimal Amount {get; set;} 
} 

public class SearchName 
{ 
    public virtual Guid Id {get set;} 
    public virtual string Name {get; set;} 
} 

// there are potentially many NameLink objects tied to a single search name 
public abstract class NameLink 
{ 
    public virtual Guid Id {get set;} 
    public virtual SearchName SearchName {get; set;} 
} 

public class NameLinkToFiler: NameLink 
{ 
    public virtual Filer Filer {get; set;} 
} 

public class NameLinkToItem: NameLink 
{ 
    public virtual Item Item {get; set;} 
} 

Meine Abfrage soll eine Liste passender Artikel Elemente zurück:

var query = session.Query<Item>() 
    .Where(x => x.Filing.Filer.Site == mySite); 

Das verbindet Verbindungs ​​Site -> Filer -> Einreichung -> Artikel funktionieren gut über meine Mappings, aber die Probleme beginnen, wenn ich versuche, den Klassen NameLinkToFiler oder NameLinkToItem basierend auf Benutzereingaben beizutreten.

Wenn der Benutzer die Abfrageergebnisse mit einem Filer Namen zu filtern, möchte ich die Ergebnisse der Artikel-Abfrage mit den Ergebnissen dieser Abfrage verbinden:

var filerNameQuery = session.Query<NameLinkToFiler>() 
.Where(q=>q.SearchName.Contains('some name')); 

ich die Ergebnisse der NameLinkToFiler wollen. Filer-Eigenschaft, um der Item.Filing.Filer-Eigenschaft beizutreten, sodass die Liste der zurückgegebenen Elemente reduziert wird.

Hinweis: Das Schlüsselwort 'Contains' oben ist eine Volltextindex-Suche, die ich wie beschrieben verwende here. Es funktioniert gut, und nehmen wir einfach an, filerNameQuery ist ein IQueryable<NameLinkToFiler>.

Es ist ziemlich einfach, dies in gerade SQL zu tun:

select filer.Name, filing.FilingDate, filer.Name, item.Date, item.Amount 
from Search_Name searchNameForFiler, Search_Name searchNameForItem, Name_Link_Filer nameLinkFiler, 
Name_Link_Item nameLinkItem, Item item, Filing filing, Filer filer, Site s 
where 
contains(searchNameForFiler.Name, :filerName) and searchNameForFiler.Id = nameLinkFiler.SearchNameId and nameLinkFiler.FilerId = filer.Id and 
contains(searchNameForItem.Name, :itemName) and searchNameForItem.Id = nameLinkItem.SearchNameId and nameLinkItem.ItemId = item.Id 
and item.FilingId = filing.Id 
and filing.FilerId = filer.Id 
and filing.SiteId = :site 

... aber ich will nicht die Kompilierung-Kontrollen für diese Art der Abfrage verlieren.

Danke.

Antwort

7

Offenbar ist die Antwort, Lambda-Syntax nicht zu verwenden.

Dies funktioniert:

query = from t in parentItemQuery 
    join l in Session.Query<NameLinkToFiler>() on t.Filing.Filer.Id equals l.Filer.Id 
    join n in Session.Query<SearchName>() on l.SearchName.Id equals n.Id 
    where sn.Contains(request.FilerName) 
    select t; 
+0

@ RadimKöhler - Hey, ich bin Sharing Art von Kerl ...;) –

+0

Im Ernst, ich genießen, was Sie tun. Es ist inspirierend ... Ich habe auch über eine intensivere Volltextnutzung nachgedacht. nett ;) –

Verwandte Themen