使用NHibernate会话加载方法,有没有办法在不初始化代理的情况下访问实体的id?

时间:2011-07-01 19:04:27

标签: nhibernate

根据文档,session.Load(id)

  

返回一个未初始化代理的对象,但实际上并没有命中数据库......

这很棒,因为我有一个场景,我想加载一个对象(我知道存在于db中)和稍后(在同一个会话中)访问实体的id,通常只有id和没有代理初始化。在我看来,如果我只访问代理的id,它不应该被初始化。至少这是我所希望的,但我似乎无法以这种方式工作。

基本上我正试图通过以下测试:

[Test]
public void Accessing_loaded_entity_id_should_not_initialize_the_proxy()
{
    // Arrange
    var repo = new NHRepository<Order>();
    var order = new OrderBuilder().Build();

    repo.Save(order);
    repo.Flush();
    repo.Clear();

    // Act
    var fromDb = repo.Load(order.ID);

    // Assert
    Assert.AreEqual(order.ID, fromDb.ID);
    Assert.IsFalse(NHibernateUtil.IsInitialized(fromDb));
} 

此测试失败:

  

Assert.IsFalse(NHibernateUtil.IsInitialized(fromDb));

更新 这是我的id的hbm映射:

<id name="id" access="field">
    <generator class="hilo">
        <param name="column">OrderNextHi</param>
        <param name="max_lo">100</param>
    </generator>
</id>

这是我的基本实体类型。我想这个问题可能就在这里,因为我很久以前就复制了这个问题,并没有考虑太多。让我知道你的想法:

public abstract class SingleIdentityDomainEntity<T> where T : SingleIdentityDomainEntity<T>
{
    private readonly int id;
    private int? _oldHashCode;

    protected SingleIdentityDomainEntity()
    {
        this.id = 0;    
    }

    public virtual int ID
    {
        get { return this.id; }
    }

    public override bool Equals(object obj)
    {
        var other = obj as T;
        if (other == null)
            return false;

        // handle the case of comparing two NEW objects
        if (other.IsTransient() && this.IsTransient())
            return ReferenceEquals(other, this);

        return other.ID.Equals(this.ID);
    }

    /// <summary>
    /// Transient objects are not associated with an item already in storage.
    /// </summary>
    public virtual bool IsTransient()
    {
        return this.ID == 0;
    }

    /// <summary>
    /// Must be provided to properly compare two objects
    /// </summary>
    public override int GetHashCode()
    {
        // Once we have a hash code we'll never change it
        if (_oldHashCode.HasValue)
            return _oldHashCode.Value;

        // When this instance is transient, we use the base GetHashCode()
        // and remember it, so an instance can NEVER change its hash code.
        if (this.IsTransient())
        {
            _oldHashCode = base.GetHashCode();
            return _oldHashCode.Value;
        }

        return this.ID.GetHashCode();
    }
}

1 个答案:

答案 0 :(得分:0)

我不知道您的存储库的实现,但我认为您的问题出在:

repo.Clear();

线。我猜它会清除你的会话(所有缓存值被逐出)。