NHibernate的。在同一会话中创建后,Bag为null

时间:2011-10-03 13:15:30

标签: c# linq nhibernate nhibernate-mapping

我有对象,其中包含对象列表。

public class Product: IProduct
{
    public virtual long     Id   { get; set; }
    public virtual string   Name { get; set; }

    public virtual IList<IFunction> Functions { get; set; }
}

public class Function : IFunction
{
    public virtual long     Id   { get; set; }
    public virtual string   Name { get; set; }

    public virtual IProduct Product { get; set; }
}

映射的对象列表(IList&lt; IFunction&gt;):

<bag name="Functions" cascade="all" table="T_WEBFUNCTIONS" lazy="false">
  <key column="PRODUCT_ID" />
  <one-to-many class="Function" />
</bag>

代码:

我尝试创建Product

的新对象
    public IProduct SetProduct(string productName)
    {
         // Product repository, which have nhibernate opened session ( ISession )
         IDBRepository<IProduct> rep = Repository.Get<IProduct>();

         // Create new object of product
         rep.Create(new Product() { Name = productName });

         // get created object by name
         prod = rep.Query().Where(x => x.Name == productName).SingleOrDefault();

         // I HAVE ISSUE HERE
         // prod.Functions == NULL. It must be a new List<Function>()
         // Nhibernate don't create empty list for me and this property always null

         return prod;
    }

BUT。当nhibernate会话关闭并再次打开时,将创建列表并包含0个项目。

如果我在同一个会话中创建一个对象(Product)并在创建后获取它,那么bag将为null。

数据存储库的功能

public class DBRepository<T> : IDBRepository<T>
{
    protected ISession CurrentSession;

    public DBRepository(ISession session)
    {
        CurrentSession = session;
    }

    public void Create(T obj)
    {
        var tmp = CurrentSession.BeginTransaction();
        CurrentSession.Save(obj);
        tmp.Commit();
    }
}

1 个答案:

答案 0 :(得分:4)

当您致电new Product()时,您的代码正在实例化一个对象而List&lt;&gt;财产开始生活为零。 NHibernate无法帮助你 - 这就是你决定做的事情(不要覆盖默认的c'tor)。

NHibernate的第一级缓存(简短说明here)在您提交事务时保存您的对象,因此当您在同一个打开的会话中通过其ID请求对象时,NHibernate会跳过从数据库中获取实体并提供服务你那同样的实例化对象。您可以使用Object.ReferenceEquals(prodYouCreated, prodRetrievedFromRepository)进行测试。

当你关闭会话时,第一级缓存被清除,下次你查询NHibernate获取数据并构建对象本身时 - 它会选择给你一个零长度列表而不是null。这是默认行为。

希望这有帮助,
Jonno