Sql NHibernate多对多标准
我有一个问题列表,每个问题都链接到一个标签列表 以及以下数据:Sql NHibernate多对多标准,sql,.net,nhibernate,icriteria,Sql,.net,Nhibernate,Icriteria,我有一个问题列表,每个问题都链接到一个标签列表 以及以下数据: Question1 : Tag1 Question2 : Tag1, Tag2 Question3 : Tag1, Tag2, Tag3 Question4 : Tag1, Tag3 以下标准: var tagsIds = new int[] { tag1, tag2 }; var res = session.CreateCriteria<Question>() .CreateCriteria( "Tags"
Question1 : Tag1
Question2 : Tag1, Tag2
Question3 : Tag1, Tag2, Tag3
Question4 : Tag1, Tag3
以下标准:
var tagsIds = new int[] { tag1, tag2 };
var res = session.CreateCriteria<Question>()
.CreateCriteria( "Tags" )
.Add( Restrictions.In( "id", tagsIds ) )
.List<Question>();
或者我只想
Question2, Question3
因为它们都有tag1和tag2。
我有办法吗
在SQL中,我将执行以下操作:
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
)
如果只有两个,则使用And限制
var res = session.CreateCriteria<Question>()
.CreateCriteria( "Tags" )
.Add( Restrictions.And(Restrictions.Eq("id", tag1), Restrictions.Eq("id", tag2))
.List<Question>();
var res=session.CreateCriteria()
.CreateCriteria(“标记”)
.添加(限制和(限制。等式(“id”,tag1),限制。等式(“id”,tag2))
.List();
如果您有两个以上或一个未知数字,请使用连词:
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>();
var conj=新连接();
//如果数字未知,则使用循环添加所有标记
联合添加(限制,等式(“id”),tag1);
联合添加(限制,等式(“id”,tag2);
var res=session.CreateCriteria()
.CreateCriteria(“标记”)
.Add(conj)
.List();
还有一个析取类来处理多个Or条件。如果只有两个Or条件,则使用And限制
var res = session.CreateCriteria<Question>()
.CreateCriteria( "Tags" )
.Add( Restrictions.And(Restrictions.Eq("id", tag1), Restrictions.Eq("id", tag2))
.List<Question>();
var res=session.CreateCriteria()
.CreateCriteria(“标记”)
.添加(限制和(限制。等式(“id”,tag1),限制。等式(“id”,tag2))
.List();
如果您有两个以上或一个未知数字,请使用连词:
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>();
var conj=新连接();
//如果数字未知,则使用循环添加所有标记
联合添加(限制,等式(“id”),tag1);
联合添加(限制,等式(“id”,tag2);
var res=session.CreateCriteria()
.CreateCriteria(“标记”)
.Add(conj)
.List();
还有一个析取类用于处理多个Or条件。使用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);
使用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));
//这是已存在的部分
var dCriteria=DetachedCriteria.For(“q”)
.SetProjection(Projections.GroupProperty(Projections.Id()))
.Add(Restrictions.Eq(Projections.Count(Projections.Id()),tagid.Length))
//这里我们根据“父”标准进行筛选
.Add(限制.EqProperty(“q.id”、“问题.id”))
.CreateCriteria(“标记”)
.添加(限制。在(“id”,TagID));
var crit=NHibernateSession
.1.标准(“问题”)
.Add(subquerys.Exists(dCriteria));
使用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);
使用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));
//这是已存在的部分
var dCriteria=DetachedCriteria.For(“q”)
.SetProjection(Projections.GroupProperty(Projections.Id()))
.Add(Restrictions.Eq(Projections.Count(Projections.Id()),tagid.Length))
//这里我们根据“父”标准进行筛选
.Add(限制.EqProperty(“q.id”、“问题.id”))
.CreateCriteria(“标记”)
.添加(限制。在(“id”,TagID));
var crit=NHibernateSession
.1.标准(“问题”)
.Add(subquerys.Exists(dCriteria));
谢谢,但这不起作用,因为它会生成以下SQL:SELECT[snipped]FROM“Question”this\uuu内部连接问题将tags3\uid标记在tags3\u3.Question\uid内部连接tag1\uu标记在tags3\uu.Tag\uid=tag1\u1.Id=2)。因此,不会返回任何内容,因为id不能同时为1和2。谢谢,但这不起作用,因为它会生成以下SQL:SELECT[snipped]FROM“Question”this_uu内部连接问题标记tags3_uu此上的tags3。id=tags3_uuuuu.Question_uid内部连接“Tag”tag1_u标记为tag1_u.id,其中(tag1_u.id=1和tag1_1.id=2)。因此不会返回任何内容,因为id不能同时为1和2