Wie

2011-01-07 12 views
1

hey guys Subqueries als Aliase mit Hilfe der Kriterien Api mit NHibernate zu schreiben, sagen, ich habe Entitäten und Zuordnungen wie folgt aus:Wie

public class Episode 
{ 
    Guid Id {get;set;} 
    String Title {get;set;} 
    List<Group> Groups {get;set;} 
} 

public class Group 
{ 
    Guid Id {get;set;} 
    DateTime PubDate {get;set;} 
} 

public class EpisodeMap : ClassMap<Episode> 
{ 
    public EpisodeMap() 
    { 
     //other mappings.. 
     Map.HasMany(ep => ep.Groups); 
    } 
} 

Also, im Grunde eine Folge viele Gruppen hat. Jede Gruppe hat ein PubDate und so hat eine Episode viele PubDates.

Ich versuche, eine Abfrage mit der NHibernate Kriterien-API zu schreiben, die ich Episoden abfragen und sie nach PubDate bestellen kann, da ich eine Gruppen-ID habe.

Im Wesentlichen wie schreibe ich die äquivalent Criteria API-Abfrage für diese SQL-Abfrage:

Select 
    e.*, 
    (Select top 1 ReleaseDate From EpisodeGroups where EpisodeFk = e.Id and GroupFk = @GroupId) as myPubDate 
From Episodes e 
Order By myPubDate 

Bitte um Hilfe! prost Jungs

Antwort

3
public DetachedCriteria BuildCriteria(int episodeId, int groupId) 
{ 

    var groupCriteria = DetachedCriteria.For<Groups>() 
     .Add(Restrictions.Eq("this.Id", groupId)) 
     .Add(Restrictions.Eq("Group.Id", groupId)) 
     .AddOrder(Order.Asc("Group.PubDate")); 

    return DetachedCriteria.For<EpisodeGroups>() 
       .Add(Restrictions.Eq("this.Id", episodeId)) 
       .Add(Subqueries.PropertyIn("this.Groups", groupCriteria) 
       .SetMaxResult(1); 
} 

Dann können Sie etwas tun ...

var episodes = _repository.ExectueCriteria<EpisodeGroups>(BuildCriteria(episodeId, groupId)) 

Gerade als besondere Berücksichtigung der Grund, warum Sie gespannt auf die Gruppe laden Entität im Fall möchten Sie möchte, Verwenden Sie LINQ, um das PUBDATE später in Ihrer Geschäftslogik zu vergleichen, anstatt ein strenges loses Kriterium zu verwenden.

Wir haben festgestellt, dass durch das eifrige Laden der Attribute einer Entity die Gesamtzahl der Aufrufe an unsere Datenbank reduziert wird.

Keine Garantien dieser Code funktioniert ... aber es sollte man zumindest den Einstieg, viel Glück :)

+0

+ 1 hey timbob, Vielen Dank. Ich habe mich wirklich mit der Kriterien-API herumgeschlagen, ich finde es sehr unintuitiv! Ich werde es versuchen und lassen Sie wissen, wie ich gehe, danke für die großartige Erklärung – andy

+0

Hey Timbob, ok, hatte nur einen kurzen Blick. Es ist fast da, aber Sie werden in meinem SQL-Beispiel feststellen, dass nur GroupId eine Variable ist. EpisodeId ist Teil der Abfrage ...? – andy

+0

Wenn ich verstehe, was Sie versuchen zu tun und wie der Rest Ihrer Entitäten zugeordnet sind, die Beschränkungen dh. (Restrictions.Eq ("this.Id", episodeId)) sollte das berücksichtigen. Ich kann mich nicht mehr erinnern, wenn Sie sowohl Gruppen als auch EpisodeGroups einen Alias ​​hinzufügen müssen, um auf ihre IDs zu verweisen. Mit anderen Worten, Sie können "this.Id" möglicherweise nicht verwenden, aber Sie müssten stattdessen "Group.Id" und "Episode.Id" verwenden. Ich hoffe das ergibt Sinn. – Timbob