NHibernate - 从投影列表中排除属性(select子句)?

时间:2009-12-31 23:26:38

标签: nhibernate hibernate hql criteria

我的课程看起来像这样

public class Agreement
{
    public virtual string ArrgKey { get; set; }
    public virtual string SubjectCode { get; set; }

    // mapped as a HasMany to AgreementStateCountyRelation
    public virtual IList<AgreementStateCountyRelation> StateCounties { get; set; }
}

public class AgreementStateCountyRelation
{
    public virtual string ArrgKey { get; set; }
    public virtual State State { get; set; } // State has a StateAbbr property
    public virtual County County { get; set; }
}

使用Fluent NHibernate,NHibernate映射非常简单。

我正在尝试编写一个查询,查找与州有关的所有协议。除了在where子句中使用之外,我根本不需要StateCounties集合的数据。使用HQL,此查询完全符合我的要求(返回TX的协议并且不会急于加载StateCounties):

var list = session.CreateQuery("select a from Agreement a 
                                join a.StateCounties sc 
                                join sc.State s 
                                where s.StateAbbr = ?")
            .SetParameter(0, "TX")
            .List<Agreement>();

当我尝试使用条件API时出现问题(我不能在这种情况下使用HQL)。我认为这会产生与HQL相同的查询:

DetachedCriteria dc = DetachedCriteria.For<Agreement>("a");
dc.CreateAlias("a.StateCounties", "sc");
dc.CreateAlias("sc.State", "s");
dc.Add(Restrictions.Eq("s.StateAbbr", "TX"));
var list = dc.GetExecutableCriteria(session).List<Agreement>();

但State的所有属性也放在select子句中(我猜是因为State在where子句中)。此外,作为同一个呼叫的一部分,县是懒惰的(即使我从来不想要或不需要它们)。

如果我指定了投影列表并设置了ResultTransformer,那么我得到的结果与HQL类似(生成相同的SQL):

DetachedCriteria dc = DetachedCriteria.For<Agreement>("a");
dc.CreateAlias("a.StateCounties", "sc");
dc.CreateAlias("sc.State", "s");
dc.SetProjection(Projections.ProjectionList()
    .Add(Projections.Property("ArrgKey"), "ArrgKey")
    .Add(Projections.Property("SubjectCode"), "SubjectCode"));
dc.SetResultTransformer(Transformers.AliasToBean<Agreement>());
dc.Add(Restrictions.Eq("s.StateAbbr", "TX"));
var agreements = dc.GetExecutableCriteria(session).List<Agreement>();

唯一的区别是StateCounties集合总是为null而不是代理,但这更好,因为我不想意外地延迟加载它们。

所以,我的问题:有没有办法告诉NHibernate在select子句(投影列表)中排除属性(StateCounties),而不是必须指定其中的所有其他属性清单?表示“此关联仅存在于where子句中使用”的内容。 ExcludeFromProjectionList或DoNotPopulate还是我可以在映射或条件中放入HasMany关系的东西?

修改:集合定义为懒惰。

作为一个精简的示例,这不会导致集合加载:

DetachedCriteria dc = DetachedCriteria.For<Agreement>("a");
var agreements = dc.GetExecutableCriteria(session).List<Agreement>();

但这样做:

DetachedCriteria dc = DetachedCriteria.For<Agreement>("a");
dc.CreateAlias("a.StateCounties", "sc");
dc.CreateAlias("sc.State", "s");
var agreements = dc.GetExecutableCriteria(session).List<Agreement>();

我刚发现这个似乎是同一个问题(没有一个好的解决方案):

https://forum.hibernate.org/viewtopic.php?t=959176

另一个有这个问题的人(不幸的是,他不能像我一样设置投影做得更好):

Making hibernate not include fields from joined tables in select clause

0 个答案:

没有答案