如何在NHibernate中同时创建父级并添加子级?

时间:2012-08-27 16:41:36

标签: c# nhibernate

当我尝试创建一个集合并同时为其添加一个类别时,我一直得到一个空引用。我忘记了什么吗?或者我做错了吗?

private static void SamepleMethod(ICollectionRepository collectionRepo)
    {
        Collection collection = new Collection { CollectionName = "Collection" };

        Category category = new Category { Collection = collection, CategoryName = "Category" };

        category.SetCollection(collection);
        collection.AddCategory(category);

        collectionRepo.Save(collection);
    }

收集:

public class Collection
{
    public virtual int? Id { get; set; }
    public virtual string CollectionName { get; set; }
    public virtual ICollection<Category> Categories { get; set; }

    public virtual void AddCategory(Category category)
    {
        Categories.Add(category);
        category.Collection = this;
    }
}

类别:

public class Category
{
    public virtual int? Id { get; set; }
    public virtual string CategoryName { get; set; }
    public virtual Collection Collection { get; set; }

    public virtual void SetCollection(Collection collection)
    {
        Collection = collection;
        collection.Categories.Add(this);
    }
}

Collection.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               namespace="ACME.Model"
               assembly="ACME.Model">

<class name="Collection" table="Collections" >

<id name="Id" column="CollectionId" type="int" >
  <generator class="identity" />
</id>

<set name="Categories" inverse="true" cascade="all">
  <key column="CollectionId" />
  <one-to-many class="Category"></one-to-many>
</set>

<property name="CollectionName">
  <column name="CollectionName" sql-type="nvarchar(50)" />
</property>

Category.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               namespace="ACME.Model"
               assembly="ACME.Model">

<class name="Category" table="Categories" >

<id name="Id" column="CategoryId" type="int" >
  <generator class="identity" />
</id>

<many-to-one name="Collection"
             class="Collection"
             column="CollectionId"
             not-null="true" />

<property name="CategoryName">
  <column name="CategoryName" sql-type="nvarchar(50)" />
</property>

2 个答案:

答案 0 :(得分:2)

您从未初始化Categories类中的Collection属性,因此它保持默认值null ...
您可能希望将其初始化为构造函数中的新集合。

另外,我计算了至少3个不同的代码行,您可以将类别与集合相关联 我相信曾经足够:)(我最喜欢AddCategory方法,或Category的ctor。

另一件小事 - hbm映射文件已成为过去;现在,在代码中映射更方便(并且更不容易出错) 您可以使用旧的扩展程序fluent nHibernate或新的官方mapping-by-code来执行此操作,这也非常好,但缺乏文档。

答案 1 :(得分:0)

(正如sJhonny指出的那样):确保初始化Categories集合

除此之外,我在您的代码中看到了其他问题(与您的问题无关):

仅初始化两个引用(从Collection到Category,反之亦然)一次。

您的代码确实:

 // set category.Collection
 Category category = new Category { Collection = collection ...
 // set collection agin
 category.SetCollection(collection);
     // within SetCollection, you add the category
     collection.Categories.Add(this);
 // and add the category agin
 collection.AddCategory(category);

看起来这个类别可以放在几个集合上,这些集合可以有几个类别。如果是这种情况,则应将其映射为many-to-many。如果它确实是正确的,请不要介意。

除非你做一些特别的事情,否则你不应该使用sql-type。只需映射如下字符串:

<property name="CategoryName" column="CategoryName" length="50" />

不鼓励使用身份主键,因为它会给您带来糟糕的性能。