nHibernate QueryOver:过滤主元素长度和子元素长度
nHibernate QueryOver: Filter length of main element and the length of sub elements
我有两个实体:Pakage
和 Pole
。 Pakage
包含多个 Poles
,在 pakage 中喜欢作为反向集。
我有一个 GUI,如果没有对 GUI 设置任何限制,它会显示所有 Pakages
。可能的限制之一是定义 Pakage
的最小长度。这很好用。但是不,我还应该在 Pakages
中显示(并考虑)Poles
的长度。因此,如果用户设置的最小长度为 2.0m,我必须显示所有长度 >= 2.0m 的 Pakages
以及包含长度 >= 2.0 的 Pole
的所有 Pakages
米
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 */
}
Pakage
中的 nHibernate 映射
<set name="Poles" table="pole" inverse="true">
<key column="pakageid" foreign-key="FK_pole_pakage" />
<one-to-many class="Pole" />
</set>
现在我想查询所有包并在网格视图中列出它们。为了过滤 pakages,我有几个数字 up 和 down 元素。首先我尝试了这个:
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
所以我将其更改为以下内容,这导致加载时间更长,因为我加载了更多元素:
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();
第二种方法不起作用,因为从 nHibernate 生成的 SQL 做了这样的事情:
WHERE (
this_.length >= @p0
OR this_.length >= @p1);
这是错误的,因为 this_
是包装。因此,这两个限制都适用于同一字段,但不适用于 pole.length 字段。
有没有解决办法select all Pakages which have a length >= the user input OR which contain a Pole which has a length the user input
您需要为加入的 table 创建别名并在限制中使用它。像这样:
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();
我有两个实体:Pakage
和 Pole
。 Pakage
包含多个 Poles
,在 pakage 中喜欢作为反向集。
我有一个 GUI,如果没有对 GUI 设置任何限制,它会显示所有 Pakages
。可能的限制之一是定义 Pakage
的最小长度。这很好用。但是不,我还应该在 Pakages
中显示(并考虑)Poles
的长度。因此,如果用户设置的最小长度为 2.0m,我必须显示所有长度 >= 2.0m 的 Pakages
以及包含长度 >= 2.0 的 Pole
的所有 Pakages
米
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 */
}
Pakage
<set name="Poles" table="pole" inverse="true">
<key column="pakageid" foreign-key="FK_pole_pakage" />
<one-to-many class="Pole" />
</set>
现在我想查询所有包并在网格视图中列出它们。为了过滤 pakages,我有几个数字 up 和 down 元素。首先我尝试了这个:
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
所以我将其更改为以下内容,这导致加载时间更长,因为我加载了更多元素:
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();
第二种方法不起作用,因为从 nHibernate 生成的 SQL 做了这样的事情:
WHERE (
this_.length >= @p0
OR this_.length >= @p1);
这是错误的,因为 this_
是包装。因此,这两个限制都适用于同一字段,但不适用于 pole.length 字段。
有没有解决办法select all Pakages which have a length >= the user input OR which contain a Pole which has a length the user input
您需要为加入的 table 创建别名并在限制中使用它。像这样:
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();