Duplicate collection role mapping nHibernate - When trying to make one - many mapping

后端 未结 1 1902
臣服心动
臣服心动 2021-01-25 07:27

I am learning nHibernate and I was trying one to many mapping. Here are the two tables Product and Product Type.

namespace NHibernateSample.Models
{
    public c         


        
相关标签:
1条回答
  • 2021-01-25 08:17

    The first issue seems to be related to wrong setting of the .hbm.xml file.. which always must have (see e.g. MappingException: No persister for - NHibernate - Persisting an Adapter)

    • xml mapping file is NOT makred as Embedded Resource
    • xml file is not part of .dll which is configured as the mapping source <mapping assembly="MyProject.Data" /> (see configuration)
    • xml file does not have the default suffix .hbm.xml

    The second question (in comment)

    Here I insert a product. I want to insert some ProductType to the database like prod.ProductTypes = new .... How can I do that

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

    solution is to adjust the mapping of the collection to be using cascading:

    <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>
    

    (what are all these settings on the <bag> - check here)

    I would adjust this POCO defintion

    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; }
        }
    }
    

    (that is just to be sure that list is initiated either by NHibernate on load or by us in other cases)

    and then we just have to assign both sides

     // 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);  
    

    And we also should adjust the mapping to be readonly for value type property

    <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>
    

    To get more details I would not miss this:

    • Minimal and correct way to map one-to-many with NHibernate
    0 讨论(0)
提交回复
热议问题