基于父类ID的NHibernate缓存对象

时间:2009-12-04 19:38:59

标签: c# nhibernate caching joined-subclass session-cache

我对动物和狗类型有以下定义。请注意,对象的ID是AnimalID:

<class name="Animal" table="Animals">
    <id name="Id" type="System.Int32" column="AnimalID">
        <generator class="identity" />
    </id>
    <property name="IsBig" column="IsBig" type="System.Bool" not-null="true" />  
</class>

<joined-subclass name="Dog" table="Dogs" extends="Animal">
    <key column="AnimalID" />
    <property name="OwnerID" column="OwnerID" type="System.Int32" non-null="true" />
    <property name="IsStrong" column="IsStrong" type="System.Bool" non-null="true" />
</joined-subclass>

假设我的数据库中包含以下信息:

in table Animals:

AnimalID    IsBig
--------    -----
10          True

in table Dogs:

AnimalID    OwnerID    IsStrong
--------    -------    --------
10          1          True
10          2          False

首先,我查询了OwnerID = 1的Dog。在同一个会话中,我查询了OwnerID = 2的Dog。由于NHibernate的Session缓存,第二个查询返回一个Dog对象,其中OwnerID = 1,IsStrong =是的,它应该返回一个Dog对象,其中OwnerID = 2,IsStrong = False。

NHibernate通过其ID(主键)列自动缓存对象,因此第二次请求Dog最终检索具有相同键的对象。我可以通过在对象上调用ISession.Evict()来解决这个问题,但这看起来像是一个黑客。

有更好的建议吗?

3 个答案:

答案 0 :(得分:1)

您必须确保为不同的实例使用不同的密钥。在您的情况下,您实际上违反了此规则:Dogs表公开了两个实例的部分共享相同的密钥

所以Dogs.AnimalID 必须被标记为主键,但在你的情况下则不是。如果将其标记为PK,则根本无法获得此类内容。

答案 1 :(得分:1)

值得尊敬的是,应该提出的问题是“我该如何正确地建模?”

你的狗狗表说狗10由拥有者1拥有并且很强壮,但是,同时,狗10由拥有者2拥有并且不强壮。

不知何故,我认为这不是你的意思。

如果您将更详细地解释您想要建模的内容,也许我们可以提出一些建议。

答案 2 :(得分:0)

使AnimalID和OwnerID成为复合主键。