我映射了以下两个类:
public class Foo
{
public virtual Guid Id { get; set; }
public virtual Bar Bar { get; set; }
}
public class Bar
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
}
我有以下标准:
return Session.CreateCriteria<Foo>("f")
.CreateAlias("f.Bar", "b")
.SetProjection(Projections.Property("f.Bar"))
.List<Bar>();
这将生成以下SQL:
select b.Id from Foo f
inner join Bar on f.BarId = b.Id
注意如何仅返回Bar的ID,而不是整个类。我如何获得Bar的所有列?
答案 0 :(得分:2)
解决方案取决于您的需求。
首先如果你需要返回实体栏,那么你的初始标准必须是Bar 类型,所以你只需:
session.CreateCriteria<Bar>().
.List<Bar();
如果你需要添加一些基于Foo的限制,那么有两种方法。
使用HQL
session.CreateQuery(
"select b " +
"from Foo f " +
"inner join f.Bar b " +
"where f.Id = 9 ")
.List();
使用仅查询属性。通过在Bar映射文件中添加access =“noop”来完成此操作。
<many-to-one name="foo" access="noop" class="Foo" column="FooFk"/>
请注意,您的域模型不必更改!您不需要在Bar类中添加“foo”属性/字段。 现在,您可以在查询中使用该属性,如:
session.CreateCriteria<Bar>()
.CreateAlias("foo", "f")
.Add(Restrictions.Eq("f.Id", 9))
.List<Bar>();
答案 1 :(得分:0)
如果不符合单一条件,请使用DetachedCriteria
:
var subquery = DetachedCriteria.For<Foo>("f")
.SetProjection(Projections.Property("f.Bar"))
// more filter criteria ...
return session.CreateCriteria<Bar>
.SetProjection(Subqueries.PropertyIn("id", subquery));
创建如下的sql:
select Bar.*
from Bar
where Bar.id in (Select b.id from Foo f inner join Bar b on ...)
如果你在子查询中有一些基于Foo的过滤条件,那么显然才有意义。
答案 2 :(得分:0)
如果上面的分离标准查询不能解决这个问题,那么应该是一个简单的HQL查询。
var hqlQuery="select b from Foo as f inner join f.Bar as b";
现在运行此查询,如下所示:
Session.CreateQuery(hqlQuery).List<Boo>();
如果需要,您现在也可以在查询中添加条件。
希望这会有所帮助..我可以告诉你如何使用Criteria做到这一点,但我认为这对你来说更容易,因为你似乎对SQL感到满意。