Using NHibernate session load method, is there a way to access an entity's id without initializing the proxy?
According to the docs, session.Load(id)
returns an object that is an uninitialized proxy and does not actually hit the 开发者_高级运维database ...
This is great as I have a scenario where I want to load an object (that I know exists in the db) and later (within the same session) access the entity's id and usually only the id AND not have the proxy initialized. It seems to me that if I only access the id of the proxy, it shouldn't have to be initialized. At least that is what I was hoping but I can't seem to get it to work that way.
Essentially I'm trying to get the following test to pass:
[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));
}
This test fails here:
Assert.IsFalse(NHibernateUtil.IsInitialized(fromDb));
Update Here's my hbm mapping of the id:
<id name="id" access="field">
<generator class="hilo">
<param name="column">OrderNextHi</param>
<param name="max_lo">100</param>
</generator>
</id>
Here's my base entity type. I'm thinking the problem might be here as I copied this a long time ago and didn't put much thought into it. Let me know what you think:
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();
}
}
I do not know your implementation of your repository but I think your problem is in the:
repo.Clear();
line. I guess it clears your session (all cache values are evicted).
精彩评论