在单个查询中查询基类和派生类

时间:2013-05-15 13:48:24

标签: nhibernate castle-activerecord

所以这对我来说似乎有点复杂,所以我会尝试尽可能清楚地设置场景。

[ActiveRecord, JoinedBase]
abstract BaseClass
{
    public x;
    public y;
}

[ActiveRecord, JoinedBase]
ClassA : BaseClass { }

[ActiveRecord, JoinedBase]
ClassB : BaseClass { }

abstract GraphicBaseClass : BaseClass
{
    public height;
    public width;
}

[ActiveRecord, JoinedBase]
ClassC : GraphicBaseClass { }

[ActiveRecord, JoinedBase]
ClassD : GraphicBaseClass { }

[ActiveRecord, JoinedBase]
ClassE : GraphicBaseClass { }

注意:在我需要输入的文字墙上保存时会忽略几个关键字和其他绒毛。

所以对它的文本解释......我们有一个标准的基类“BaseClass”,它实现了许多属性。然后,我们有几个类“ClassA”和“ClassB”,它们是特定类型的基础。然后我们使用一个中间基类“GraphicBaseClass”来添加高度和宽度属性,剩下的3个类继承这些属性。这导致单个BaseClass公共表,以及每个具体类的5个特定表。

我有一个查询,大部分都在基本属性上工作。在某些情况下,我想查询高度和宽度。由于GraphicBaseClass不是activerecord类,因此我不能将其用作查询的基础。目前我正在使用QueryOver语法,但我找不到使用height和width属性查询三个GraphicBaseClass派生实体的方法。

我到目前为止最接近的是:

QueryOver<BaseClass, BaseClass> query = QueryOver.Of<BaseClass>()
    .Where(bc => bc.x == something)
    .TransformUsing(CriteriaSpecification.DistinctRootEntity);
if (actualTypes.All(x => x.IsSubclassOf(typeof (GraphicBaseClass))))
{
    // Filter by dimensions
    if (criteria.RestrictSize)
    {
        if (criteria.FilterByDimension)
        {
            query.DetachedCriteria.Add(Restrictions.Lt("Width", criteria.Width + 10));
            query.DetachedCriteria.Add(Restrictions.Lt("Height", criteria.Height + 10));
        }
    }
}

这导致sql类似于:

SELECT TOP (4 /* @p0 */) this_.BaseClassId as BaseClass1_97_5_,
                 this_.Version                   as Version97_5_,
                 this_.BaseClassType          as BaseClass2_97_5_,
                 this_1_.Width                   as Width99_5_,
                 this_1_.Height                  as Height99_5_,
                 this_2_.Width                   as Width100_5_,
                 this_2_.Height                  as Height100_5_,
                 this_3_.X                       as X101_5_,
                 this_4_.Width                   as Width102_5_,
                 this_4_.Height                  as Height102_5_,
                 this_5_.X                       as X103_5_,
FROM   BaseClass this_
       left outer join ClassC this_1_
         on this_.BaseClassId = this_1_.ClassCId
       left outer join ClassD this_2_
         on this_.BaseClassId = this_2_.ClassDId
       left outer join ClassA this_3_
         on this_.BaseClassId = this_3_.ClassAId
       left outer join ClassE this_4_
         on this_.BaseClassId = this_4_.ClassEId
       left outer join ClassB this_5_
         on this_.BaseClassId = this_5_.ClassBId
WHERE  and this_1_.Width between 0 /* @p8 */ and 'Height' /* @p9 */

所以它只将高度和宽度限制应用于3个必需类之一。

我在这里寻找任何答案,如果它可以在HQL或Criteria API中完成,或者是为了达到结果所需要的。

为文本墙道歉!!

感谢。

1 个答案:

答案 0 :(得分:2)

有点晚了,我知道。这是我经常使用的解决方案:

创建子查询并将其与&#34; in&#34;。

连接
if (/* subclass required*/)
{
  var subClassQuery = QueryOver.Of<GraphicBaseClass>();
  subClassQuery.Where(x => x.Width  == criteria.Width);
  subClassQuery.Where(x => x.Height == criteria.Height);
  subClassQuery.Select(x => x.Id);
  query.Where(Subquery.WherePropery(x => x.Id).In(subClassQuery));
}