NHibernate many-to-many-Kriterien
-
08-10-2019 - |
Frage
Ich habe eine Liste von Fragen, die jeweils auf eine Liste von Variablen verknüpft.
Und die folgenden Daten:
Question1 : Tag1
Question2 : Tag1, Tag2
Question3 : Tag1, Tag2, Tag3
Question4 : Tag1, Tag3
Die folgenden Kriterien:
var tagsIds = new int[] { tag1, tag2 };
var res = session.CreateCriteria<Question>()
.CreateCriteria( "Tags" )
.Add( Restrictions.In( "id", tagsIds ) )
.List<Question>();
gibt (Ich verstehe, warum die "in" wirkt wie ein OR)
Question1, Question2, Question3, Question4
Oder ich möchte nur bekommen
Question2, Question3
, da sie beide haben tag1 und tag2. Ich es eine Möglichkeit, es zu tun?
In SQL, ich möchte etwas tun:
SELECT *
FROM Question q
WHERE EXISTS (
SELECT *
FROM QuestionsToTags qtt
WHERE qtt.Question_id = q.Id
AND qtt.Tag_id IN ( 1, 2 )
GROUP BY qtt.Question_id
HAVING COUNT( qtt.Question_id ) >= 2
)
Lösung 2
Mit hql:
var q = NHibernateSession.CreateQuery(
@"from Question question
where exists(
select q.id from Question q
join q.Tags t
where
t.id in (:ids)
and q.id = question.id
group by q.id
having count(t.id)=:c_count )");
q.SetParameterList("ids", tagIds);
q.SetInt32("c_count", tagIds.Length);
Und mit einem ICriteria:
// here is the exists part
var dCriteria = DetachedCriteria.For<Question>("q")
.SetProjection(Projections.GroupProperty(Projections.Id()))
.Add(Restrictions.Eq(Projections.Count(Projections.Id()), tagIds.Length))
// here we filter on the "parent" criteria
.Add(Restrictions.EqProperty("q.id", "question.Id"))
.CreateCriteria("Tags")
.Add(Restrictions.In("id", tagIds));
var crit = NHibernateSession
.CreateCriteria<Question>("question")
.Add(Subqueries.Exists(dCriteria));
Andere Tipps
Wenn Sie nur zwei verwendet dann eine Einschränkung Und
var res = session.CreateCriteria<Question>()
.CreateCriteria( "Tags" )
.Add( Restrictions.And(Restrictions.Eq("id", tag1), Restrictions.Eq("id", tag2))
.List<Question>();
Wenn Sie mehr als zwei oder eine unbekannte Zahl dann Conjunction verwenden:
var conj = new Conjunction();
// use a loop to add all tags if number is unknown
conj.Add(Restrictions.Eq("id", tag1);
conj.Add(Restrictions.Eq("id", tag2);
var res = session.CreateCriteria<Question>()
.CreateCriteria( "Tags" )
.Add(conj)
.List<Question>();
Es gibt auch eine Disjunktion Klasse Griff Mehrfach- oder Bedingungen.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow