2011-09-19 75 views
1

我有一个使用NH 3.1的项目,并且迄今为止一直使用QueryOver语法。NHibernate QueryOver值集合

该项目的一个方面是在一个组织范围内的数据库中,我拥有只读访问权限并且使用了完全不同的DBMS(Oracle vs MSSQL)。所以我存储从我的对象(FOOS)引用它们的对象(酒吧)使用标准的多对许多表

FooBars 
FooID int not null PK 
BarID int not null PK 

我的域对象,而不是具有Iset<Bar>,而不是具有手动映射的ISet<int> BarIDsFooBars表。这可以防止NH尝试做不可能的事情,并且一直加入到Bars表中(如果我需要它们,我可以使用BarRepository.Get()来检索Bars的细节,在这种情况下,我会't,因为我只需要这些ID来筛选返回的对象列表)。

鉴于IList<int> SelectedBars我该怎么写QueryOver<Foo>其中BarIDs包含SelectedBars中的任何元素?

SQL类似

...FROM foos INNER JOIN foobars on foo.fooID = foobars.fooID WHERE barID IN (...) 

回答

0

所以3年后,我回来报告我是如何解决这个问题的。

public class Foo :Entity { 
    public virtual ISet<FooBar> BarIDs { get; protected internal set; } 
} ... 

public class FooBar :Entity { 
    protected internal FooBar() { } 
    protected internal FooBar(Foo f, int BarID) { ... } 
    public virtual Foo Foo { get; protected internal set; } 
    public virtual int BarID { get; protected internal set; } 
} 

这基本上是Stefan建议的内容,以及相关文章中的暗示。你只需要花费额外的实体和引用它的开销。请记住,我正在存储BarID而不是完整的Bar对象,因为我正在处理两个数据库之间的硬边界:Bars存储在与Foos不同的平台上的完全不同的数据库中。否则,当然,你告诉Foo它有一个ISet<Bar>要好得多。

查找FOOS通过SelectedBarIDs是那么容易的,就像Thilak建议:

session.QueryOver<Foo>().JoinQueryOver<FooBar>(f => f.BarIDs). 
    WhereRestrictionOn(b => b.BarID).IsIn(...)... 

这是一个有趣的问题,遇到像这样的数据库边界的工作。我不能说我喜欢这样做,但如果其他人要花时间维护一个酒吧列表并将其提供给我使用,那么对我来说这将是一个巨大的浪费资源。因此,使用包装类的低效率是一个非常简单的成本。

1

尝试:

session.QueryOver<Foo>() 
     .JoinQueryOver(x => x.FooBars) 
     .WhereRestrictionOn(x => x.BarId).IsIn(...) 
2

这是不可能的QueryOver。两年前,我有一个similar question about filtering value collections。 (注意:QueryOver基于Criteria API)。

我不是100%确定,但它可能适用于HQL。它更强大。

您可能会在QueryOver条件中包含SQL语句。

我不明白你为什么不把它映射为实体列表。有懒惰的加载以避免不必要的加载 - 虽然有时候会有一些折衷。您可以在不碰到数据库的情况下访问NH代理的ID。映射ID通常会让生活变得更加困难。

+0

是的,我有这种徒劳的希望,也许事情会在两年内发生改变。延迟加载将不起作用,因为如果我不小心,它会尝试访问数据库,然后尝试将MSSQL数据库中的表加入Oracle数据库。但是我可以编写一个只有ID作为其唯一属性的包装类“DummyBar”......只需让automapper忽略它即可。 –

+0

回到这两个月之后...我曾尝试编写一个BarProxy类,但是当它开始查询“找到与此栏有关系的foos”时,SQL试图加入BarProxy表,a)不存在,b)即使它确实存在也是空的(真实数据在外部数据库中)。所以我想现在我们会尝试HQL或原始SQL。 –