Используя метод загрузки сеанса NHibernate, есть ли способ получить доступ к идентификатору объекта без инициализации прокси? - PullRequest
1 голос
/ 01 июля 2011

Согласно документации, session.Load (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));

Update Вот мое отображение 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 голосов
/ 02 июля 2011

Я не знаю вашу реализацию вашего хранилища, но я думаю, что ваша проблема в:

repo.Clear();

линия. Я предполагаю, что это очищает ваш сеанс (все значения кэша удалены).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...