如何为内连接添加限制?

时间:2010-10-22 17:33:33

标签: c# nhibernate

我有以下NHibernate DetatchedCriteria,

return DetachedCriteria.For<MMFund>()
    .CreateCriteria<MMFund>(x => x.DataUniverse)
    .Add<DataUniverse>(x => x.SiteId == 100)
    .SetProjection(LambdaProjection.Property<MMFund>(x => x.FundId));

生成以下SQL:

and
    this_.ShareClassReturn_ShareClassId in 
    (
        SELECT f.[Fund_ID] as y0_
        FROM   
            dbo.Fund f inner join CAP.DataUniverse du
              on f.[Fund_TypeID] = du.[DataUniverse_TypeId]
                 and f.[Fund_CountryID] = du.[DataUniverse_CountryID]
        WHERE  fu.[DataUniverse_SiteId] = 100
    )

DataUniverse中有很多资金。

我需要对此进行过滤,以便我只能选择国家/地区ID为“ET”的资金,以便我的查询如下所示:

and
    scr.ShareClassReturn_ShareClassId in 
    (
        /* Get funds in universe */
        SELECT f.[Fund_ID] as y0_
        FROM   dbo.Fund f inner join CAP.DataUniverse du
                    on f.[Fund_TypeID] = du.[DataUniverse_TypeId]
                    and f.[Fund_CountryID] = 'ET' // these are the guys I need
        WHERE  du.[DataUniverse_SiteId] = 100 
    )

但是,我不确定我需要对DetachedCriteria做些什么来实现这一目标。我遇到的问题是无论我做什么,它都会把条款放在错误的地方,例如

WHERE  du.[DataUniverse_SiteId] = 100  and f.Fund_CountryId = 'ET'

当我添加以下行.Add(Restrictions.Eq("CountryId", "ET"))

return DetachedCriteria.For<MMFund>()
    .Add(Restrictions.Eq("CountryId", "ET"))
    .CreateCriteria<MMFund>(x => x.DataUniverse)
    .Add<DataUniverse>(x => x.SiteId == 100)
    .SetProjection(LambdaProjection.Property<MMFund>(x => x.FundId));

或当我指定限制应该是第二个.CreateCriteria的一部分时,它会尝试完全过滤错误的表,例如

return DetachedCriteria.For<MMFund>()
    .CreateCriteria<MMFund>(x => x.DataUniverse)
        .Add(Restrictions.Eq("CountryId", "ET"))
    .Add<DataUniverse>(x => x.SiteId == 100)
    .SetProjection(LambdaProjection.Property<MMFund>(x => x.FundId));

产生这个;

WHERE  du.[DataUniverse_SiteId] = 100  and du.[DataUniverse_CountryID] = 'ET'

**注意 - 因为我正在使用Criteria API,这实际上是我正在使用的限制:

.Add<MMFund>(f => f.CountryId == "ET")

我使用Restriction术语,因为它更清楚我想要实现的目标。 Criteria API&amp;另一种方式产生完全相同的结果。

1 个答案:

答案 0 :(得分:0)

为什么您认为Where是过滤器的错误位置?这就是过滤发生的地方。

生成的SQL看起来很合理。您在其公共字段上连接了两个表。 Where子句提供适当的过滤信息。如果您的首选 SQL语句已到位,则您只能在TypeID上加入数据,而不是CountryID。

例如,假设您的Fund表看起来像这样

TypeID    CountryID
1         1
1         2
2         1
2         2
3         1
4         1

您的DataUniverse表格如下

TypeID    CountryID
1         1
1         2
1         3
2         1
2         2
2         3
3         1
3         2
4         1
4         2

如果您像 那样编写SQL,那么您将根据TypeID生成一个联接,例如,您可以过滤Fund.CountryID = 1。你的产品会是什么样子?

F.TypeID    F.CountryID    D.TypeID    D.CountryID
1           1              1           1
1           1              1           2
1           1              1           3
2           1              2           1
2           1              2           2
2           1              2           3
3           1              3           1
3           1              3           2
4           1              4           1 
4           1              4           2

这是你想要的输出吗?是的,您已经过滤了Fund.CountryID,但您的加入仅在TypeID上,因此您已获得DataUniverse的所有记录,其中每个Fund的匹配类型。

在两个字段上加入,Where过滤CountryID,结果将如下

F.TypeID    F.CountryID    D.TypeID    D.CountryID
1           1              1           1
2           1              2           1
3           1              3           1
4           1              4           1 

问题是您期望哪一组数据?