杜曼:
class Action
Products: IList of class ActionProducts:
Category: class Category
Products: IList of class Product
现在,我想要这个:
var products = from a in Session.Linq<Action>()
from ap in a.Products
from p in ap.Category.Products
where a.Name == name
select p;
这个Linq实际上可以工作但是:1。为所有表而不是仅产生选择2.产生左外连接,而不是内部3.查询上的Distinct()不起作用(尽管ToList()。Distinct( )工作)。
也可以使用SelectMany(a =&gt; a.Products).SelectMany(ap =&gt; ap.Category.Products),但它对当前的NHibernate.Linq根本不起作用。
所以我想使用ICriteria。但我看不出如何退货而不是行动?
ICriteria criteria = Session.CreateCriteria(typeof(Action))
.Add(Expression.Eq("Name", name))
.CreateAlias("Products", "ap")
.CreateAlias("ap.Category.Products", "p")
.SomehowReturnMeOnly("p");
那我该怎么回事只能回答(“p”)?所以我可以做到
return criteria.List<Product>();
哪个会失败,因为ICriteria会选择Actions而不是Products?
我可能会考虑使用HQL,但实际上我并不喜欢字符串查询...例如,这里的HQL可以工作并生成我需要的SQL:
IQuery query = Session.CreateQuery("select distinct p from Action a inner join a.Products as ap inner join ap.Category.Products as p");
return query.List<Product>();
答案 0 :(得分:2)
现在,可以使用
完成类似的事情(记住CreateAlias只能做1级) DetachedCriteria dq = DetachedCriteria.For<Action>()
.Add(Expression.Eq("Name", name))
.CreateAlias("Products", "ap")
.CreateAlias("ap.Category", "c")
.CreateAlias("c.Products", "p")
.SetProjection(Projections.Property("p.Id"));
ICriteria criteria = Session.CreateCriteria(typeof(Product))
.Add(Subqueries.PropertyIn("Id", dq));
return criteria.List<Product>();
这可以工作并通过测试,但会生成“SELECT FROM products WHERE id in(subquery)”,这可能更好(不需要DISTINCT)但不是我想要实现的。似乎Criteria API非常非常严格。所以我们有:
所以我想在Linq准备好之前我会坚持使用HQL。
答案 1 :(得分:1)
您需要使用预测,如下所示:
ICriteria criteria = Session.CreateCriteria(typeof(Action))
.Add(Expression.Eq("Name", name))
.CreateAlias("Products", "ap")
.CreateAlias("ap.Category.Products", "p")
.SetProjection(Projections.Property("ap.Category.Products"))
.List<Product>();
在某些示例中,请查看nhibernate docs here。
答案 2 :(得分:0)
好吧,在考虑了克里斯的回答之后......我试过这个并且似乎有效:
ICriteria criteria = Session.CreateCriteria(typeof(Action))
.Add(Expression.Eq("Name", name))
.CreateAlias("Products", "ap")
.CreateAlias("ap.Category", "c")
.SetProjection(Projections.Distinct(Projections.Property("c.Products")));
看起来NHibernate不允许深度嵌套投影属性,这很奇怪。并且它也不起作用,查看生成的SQL我发现它只选择
SELECT distinct c2_.Id as y0_ FROM ... Categories c2_ ...
即。它并没有真正获取产品,这使我的单元测试失败,因为返回的列表只包含空值而不是产品实例。