我有一个人物对象,可以拥有无限数量的名字。所以名字是另一个对象。
即
人---姓名
---名字
---名字
我想要做的是编写一个禁止查询,使用该查询会得到一个具有某些名字的人。
因此,一个查询可能会找到名字为alison,jane和philippa的人,然后下一个查询可能会找到一个名字为alison and jane的人。
我只想归还拥有我所搜索的所有名字的人。到目前为止我已经
了ICriteria criteria = session.CreateCriteria(typeof (Person));
criteria.CreateAlias("Names", "name");
ICriterion expression = null;
foreach (string name in namesToFind)
{
if (expression == null)
{
expression = Expression.Like("name.Value", "%" + name + "%");
}
else
{
expression = Expression.Or(
expression,
Expression.Like("name.Value", "%" + name + "%"));
}
}
if (expression != null)
criteria.Add(expression);
但这会让每个人都找到我正在搜索的名字,而不是所有的名字。
任何人都可以帮我解决这个问题吗?谢谢!
答案 0 :(得分:1)
那么它不应该是一个AND表达吗?
像这样:
ICriteria criteria = session.CreateCriteria(typeof (Person));
criteria.CreateAlias("Names", "name");
foreach (string name in namesToFind)
{
criteria.Add(Expression.Like("name.Value", "%" + name + "%"));
}
修改强>
确定。要匹配您在上面提供的查询,请稍加更改以避免加入:
ICriteria criteria = s.CreateCriteria(typeof(Person));
foreach (string name in namesToFind)
{
criteria.Add(Subqueries.PropertyIn("Id",
DetachedCriteria.For<Name>()
.Add(Restrictions.Like("Value", name, MatchMode.Anywhere))
.SetProjection(Projections.Property("Person"))));
}
这要求您在Name类上有一个名为Person的映射属性。
答案 1 :(得分:0)
有多种方法可以做到这一点。您可以为每个名称使用exists子查询。或者,您可以加入名称,为每个名称添加name like '%blah%'
,逐个添加having count(*) = nameCnt
。但是,ICriteria不支持Having子句,因此您需要使用HQL。
答案 2 :(得分:0)
这是我想要获得的那种sql:
select * from person where Id in
(
select person.id from person inner join [name]
on person.id = name.personId
where name.value like '%jane%'
)
and id in
(
select person.id from person inner join [name]
on person.id = name.personId
where name.value like '%janice%'
)
and id in
(
select person.id from person inner join [name]
on person.id = name.personId
where name.value like '%louise%'
)