【问题标题】:Rename NHibernate criteria重命名 NHibernate 条件
【发布时间】:2014-11-22 03:18:40
【问题描述】:

我正在尝试多次加入别名,但这取决于它应该执行的次数。

Employee employeeAlias = null;
Thing thingAlias = null;
var names = string[] {"A", "B", "C", "D", "E"} // number of values could vary
for(int i = 0; i < names.Length ; i++)
{
   queryOver
       .JoinAlias(() => employeeAlias.Things, 
                  () => thingAlias,
                  JoinType.LeftOuterJoin, 
                  Restrictions.Eq(Projections.Property(() => thingAlias.Name, 
                                  names[i]));
}

然而,在执行时,NHibernate 会抛出一个错误:

NHibernate.QueryException: duplicate alias: thingAlias ---&gt; System.ArgumentException: An item with the same key has already been added

有没有办法让 NHibernate 加入具有指定名称的别名,这样它就不会重复使用变量的名称?

谢谢各位。从昨天开始,这一直是我的问题,我找不到合适的解决方案。

PS:

我正在尝试做这样的事情:

SELECT * FROM Employee e
LEFT OUTER JOIN Thing t on e.Id = t.EmployeedId AND t.Name = "A"
LEFT OUTER JOIN Thing t on e.Id = t.EmployeedId AND t.Name = "B"

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate


    【解决方案1】:

    你想要达到的目标是不可能的。每个关系(many-to-oneone-to-many)只能使用一次。

    为支持此声明,请在此处查看:CriteriaQueryTranslator.cs

    private void CreateAssociationPathCriteriaMap()
    {
        foreach (CriteriaImpl.Subcriteria crit in rootCriteria.IterateSubcriteria())
        {
            string wholeAssociationPath = GetWholeAssociationPath(crit);
            try
            {
                associationPathCriteriaMap.Add(wholeAssociationPath, crit);
            }
            catch (ArgumentException ae)
            {
                throw new QueryException("duplicate association path: "
                                        + wholeAssociationPath, ae);
            }
    

    所以,我们在这里可以看到,不管别名如何,最后,所有关联关系(JOINS)都添加到associationPathCriteriaMap,即IDictionary&lt;string, ICriteria&gt;

    这意味着,现在有办法让两个相同的键发挥作用......

    【讨论】:

    • 请看一下我上次的编辑。你知道我如何在 nhibernate 中做到这一点吗?我之前问我的问题的原因是因为我认为这种方式是实现我想要的 sql 脚本的正确方式。
    • 我想说,唯一的或方法是将更多集合映射到同一个表。你需要使用 WHERE 来过滤它们。我的意思是拥有 Things1、Things2、Things3,然后您可以根据需要加入它们。检查nhforge.org/doc/nh/en/index.html#collections-mapping属性where
    • 但这是否意味着我将对其进行硬编码?连接数是动态的。不能硬编码 things1, things2, things3.. :(
    • 没错。但这是 NHibernate 的 解决方案。它就是这样设计的。如果您想将某些内容放入查询 1) 关系必须存在 2) 只能使用一次。但我想说,问题是:你为什么需要它?过滤?那么你应该改变方法并使用I. 子查询(你可以有很多子查询),然后用他们的结果过滤II. 根查询......也许检查这个答案stackoverflow.com/a/23905744/1679310 我展示了如何使用 Subqueries 。 .. 真的很重 ;)
    • 那种。我想检查行是否在名称列中包含某个值。这就是为什么我对每个值都使用左外连接。
    【解决方案2】:

    我没有尝试过,但我认为我们可以(不确定,但如果你没有尝试过)使用 Restrictions.In 而不是使用 for-loopRestrictions.Eq 喜欢-

    Restrictions.In(Projections.Property(() => thingAlias.Name, names));
    

    【讨论】:

    • 不。我想将每个名称投影到一个列中:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 2015-11-26
    相关资源
    最近更新 更多