2009-06-04 8 views
1

Hier sind meine relevanten Klassen:NHibernate-Abfrage für den Abgleich Alle Tags

public class Item { 
    public virtual int Id { get; protected set; } 
    public virtual IList<Tag> Tags { get; set; } 
} 

public class Tags { 
    public virtual int Id { get; protected set; } 
    public virtual string Name { get; set; } 
    public virtual IList<Item> Items { get; set; } 
} 

Diese sind mit einem viel zu viele Vereinigung abgebildet. Die Zwischentabelle heißt ItemsToTags.

Hier ist die Frage:

eine Liste von Strings gegeben, wie erstelle ich eine NHibernate-Abfrage, die alle Item s zurückgibt, die alle Tag s mit Name s haben alle Fäden in der angegebenen Liste passender?

Dies ist die Funktion Signatur:

IList<Item> GetItemsWithTags(IList<string> tagNames); 

Ich brauche so etwas wie:

from Item item 
where !tagsNames.Except(
    from item.Tags select item.Tags.Name 
).Any() 
select item 

Vielen Dank im Voraus für jede Hilfe.

+0

Entschuldigung, ich habe Ihre Frage falsch gelesen und habe nicht bemerkt, dass Sie * alle * Tags benötigen, um zu passen. Ich weiß, wie man das mit SQL macht, aber ich muss darüber nachdenken, wie man es mit NHibernate macht ... Ich habe in der Zwischenzeit meine falsche Antwort gelöscht. –

Antwort

2

Sie können dies auf jeden Fall mit HQL tun; Ich habe es erfolgreich getestet.

var items = session.CreateQuery("SELECT i.Id FROM Item i JOIN i.Tags tags WHERE tags.Name IN(:tags) GROUP BY i HAVING COUNT(DISTINCT tags) = :tagCount") 
     .SetParameterList("tags", tagNames) 
     .SetInt32("tagCount", tagNames.Count) 
     .List(); 

dass Sie eine Liste von Item IDs erhalten, die Sie erhalten die Item s nutzen können. Die GROUP BY und HAVING Kombination können in einigen DBMS jedoch ineffizient sein. Es gibt eine andere Abfragemethode, die iterative Joins verwendet, die möglicherweise effizienter auf bestimmten DBMS ist, aber ich kann es nicht zum Funktionieren bringen (möglicherweise überhaupt nicht möglich mit Kriterien). Wenn ich das jemals tue, werde ich meine Antwort aktualisieren.

+0

Das funktioniert, danke. Für zukünftige Referenz, auf welchen Systemen könnte dies ineffizient sein? – kuhlmancer

+0

Die Website mysql.com schlägt vor, dass MySQL eine temporäre Tabelle mit filesort verwendet: http://forge.mysql.com/wiki/TagSchema#Items_Having_All_of_A_Set_of_Tags Dies könnte jedoch veraltet oder verbessert sein. Ich habe keine umfassende Analyse durchgeführt und weiß nicht genug über Abfrage-Module im Allgemeinen, um zu sagen, ob dies ein häufiges Problem ist, weshalb ich gestresst habe * kann * :) –

Verwandte Themen