问题描述
我有两个实体:Pakage
和Pole
。 Pakage
包含多个Poles
,它们在打包时都喜欢作为反向集。
我有一个GUI,如果没有在GUI上设置任何限制,它会显示所有Pakages
。可能的限制之一是定义Pakage
的最小长度。这很棒。但我不应该在Poles
中显示(并考虑)Pakages
的长度。因此,如果用户将最小长度设置为2.0m,则我必须显示所有长度大于等于2.0m的Pakages
,以及所有包含长度大于等于2.0的Pakages
的{{1}} m。
Pole
public class Pakage : IComparable
{
public virtual decimal Length { get; set; }
public virtual ISet<Pole> Poles { get; set; } = new HashSet<Pole>();
/* other stuff */
}
public class Pakage : IComparable
{
public virtual decimal Length { get; set; }
/* other stuff */
}
中的nHibernate映射
Pakage
现在,我想查询所有包装并在网格视图中列出它们。为了过滤包,我有几个数字上下元素。首先,我尝试了这个:
<set name="Poles" table="pole" inverse="true">
<key column="pakageid" foreign-key="FK_pole_pakage" />
<one-to-many class="Pole" />
</set>
这给了我一个错误:var query = session.QueryOver<Pakage>();
if (seLengthFrom.EditValue != null)
{
query.Where(pakage => pakage.Length >= seLengthFrom.Value || pakage.Poles.Count(p => p.Length >= seLengthFrom.Value) > 0);
}
因此我将其更改为以下内容,由于加载了更多元素,因此导致加载时间更长:
'variable 'pakage' of type 'App.Pakage' referenced from scope '',but it is not defined
第二种方法不起作用,因为从nHibernate生成的sql做了这样的事情:
var query = session.QueryOver<Pakage>();
var poleJoin = query.Left.JoinQueryOver(pakage => pakage.Pole);
if (seLengthFrom.EditValue != null)
{
query.Where(
Restrictions.disjunction()
.Add(Restrictions.Where<)Pakage>(x => x.Length >= seLengthFrom.Value))
.Add(Restrictions.Where<Pole>(z => z.Length >= seLengthFrom.Value))
);
}
IList<Pakage> pakageList = query.TransformUsing(Transformers.distinctRootEntity).List();
这是错误的,因为WHERE (
this_.length >= @p0
OR this_.length >= @p1);
是包装。因此,这两个限制都在同一字段上起作用,而在pole.length字段上却没有。
this_
的解决方案
解决方法
您需要为联接表创建别名并在限制中使用它。像这样:
Pole poleJoin = null; // <- created alias
session.QueryOver<Pakage>()
.JoinAlias(x => x.Poles,() => poleJoin,JoinType.LeftOuterJoin)
.Where(x => x.Length >= seLengthFrom.Value) || poleJoin.Length >= seLengthFrom.Value))
.Select(Projections.RootEntity())
.TransformUsing(Transformers.DistinctRootEntity)
.List();