重复的集合角色映射nHibernate - 尝试进行一次多次映射时

时间:2016-10-15 09:01:35

标签: c# asp.net-mvc nhibernate nhibernate-mapping

我正在学习nHibernate,我正在尝试一对多的映射。以下是产品和产品类型的两个表格。

namespace NHibernateSample.Models
{
    public class Product
    {
        public virtual Guid Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Category { get; set; }
        public virtual bool Discontinued { get; set; }
        public virtual IList<ProductType> ProductTypes { get; set; }
    }
}

以下是我的映射XML

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="NHibernateSample"
               namespace="NHibernateSample.Models">

  <!-- more mapping info here -->
  <class name="Product">
    <id name="Id">
      <generator class="guid" />
    </id>
    <property name="Name" />
    <property name="Category" />
    <property name="Discontinued" />

    <bag name="ProductTypes">
      <key column="ProductID" />
      <one-to-many class="NHibernateSample.Models.ProductType,NHibernateSample" />
    </bag>
  </class>
</hibernate-mapping>

产品类型xml:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="NHibernateSample"
               namespace="NHibernateSample.Models">

  <!-- more mapping info here -->
  <class name="ProductType">
    <id name="ProductTypeID">
      <generator class="increment"/>
    </id>
    <property name="ProductType1" column="ProductType"/>
    <property name="ProductID" />
    <many-to-one name="Product" class="Product">
      <column name="ProductID" sql-type="int" not-null="true"/>
    </many-to-one>
  </class>
</hibernate-mapping>

映射在配置

mapping assembly="NHibernateSample" /> 

当我尝试配置和构建会话工厂时

var cfg = new Configuration();
cfg.Configure();
m_SessionFactory = cfg.BuildSessionFactory();

我得到的错误是&#34;关联引用未映射的类:NHibernateSample.Models.ProductType&#34;但是我在bin文件夹中看到了hbm文件。

如果我明确添加程序集,

Assembly thisAssembly = typeof(Product).Assembly;
cfg.AddAssembly(thisAssembly);

我得到另一个错误说&#34;复制集合角色映射NHibernateSample.Models.Product.ProductTypes&#34;

我做错了什么?这不是我应该映射外键的方式吗? 提前致谢

1 个答案:

答案 0 :(得分:1)

第一个问题似乎与.hbm.xml文件的错误设置有关..它总是必须有(参见例如MappingException: No persister for - NHibernate - Persisting an Adapter

  • xml映射文件不是嵌入式资源
  • xml文件不是.dll的一部分,它被配置为映射源<mapping assembly="MyProject.Data" />(参见配置)
  • xml文件没有默认后缀.hbm.xml

第二个问题(评论中)

  

我在这里插入一个产品。我想插入一些ProductType   数据库如prod.ProductTypes = new ....我该怎么做

Product prod = new Product(); 
prod.Name = "Q3"; prod.Category = "Audi"; 
prod.Discontinued = false; 
session.Save(prod);  
...

解决方案是调整集合的映射以使用级联:

<class name="Product">
    <id name="Id">
      <generator class="guid" />
    </id>
    <property name="Name" />
    <property name="Category" />
    <property name="Discontinued" />

    <bag name="ProductTypes" 
      lazy="true" inverse="true" batch-size="25" cascade="all-delete-orphan"
     >
      <key column="ProductID" />
      <one-to-many class="NHibernateSample.Models.ProductType,NHibernateSample" />
    </bag>

</class>

<bag>上的所有这些设置 - 检查here

我会调整这个POCO定义

public class Product
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Category { get; set; }
    public virtual bool Discontinued { get; set; }

    //public virtual IList<ProductType> ProductTypes { get; set; }
    IList<ProductType> _productTypes;
    public virtual IList<ProductType> ProductTypes
    {
        get { return _productTypes ?? (_productTypes = new List<ProductType>()); }
        set { _productTypes = value; }
    }
}

(这只是为了确保列表是由NHibernate在加载时启动的,还是由我们在其他情况下启动的)

然后我们只需分配双方

 // product
 Product prod = new Product(); 
 prod.Name = "Q3"; prod.Category = "Audi"; 
 prod.Discontinued = false; 

 // product type
 ProductType productType = new ProudctType();
 ...

 // both sides assigned
 prod.ProductTypes.Add(productType);
 productType.Product = prod;

 session.Save(prod);  

我们还应该将映射调整为值类型属性

的只读
<property name="ProductID" insert="false" update="false" />
<many-to-one name="Product" class="Product">
  <column name="ProductID" sql-type="int" not-null="true"/>
</many-to-one>

要获得更多细节,我不会错过这个: