NHibernate没有插入孩子

时间:2016-04-29 13:05:30

标签: c# nhibernate nhibernate-mapping

我正在构建一个MultiLingual应用程序,其中包含一些动态翻译。因此,我选择为产品制作单独的表格,包括翻译。

不,我在插入翻译时遇到麻烦,它们是产品的一部分。插入了哪个。

  <class name="Product" table="Product">
    <id name="Id">
      <generator class="native" />
    </id>
    <property name="SomeOtherStuff" column="SomeOtherStuff" />
    <set name="NaamTranslations" cascade="all">
      <key column="ProductId" not-null="true" />
      <one-to-many class="ProductTranslation" />
    </set>
  </class>

  <class name="ProductTranslation"
         table="ProductTranslation" lazy="false">
    <id name="Id">
      <generator class="native" />
    </id>
    <many-to-one name="Product" column="ProductId" not-null="true" 
                 index="UQ_ProductTranslation" class="Product"
                 cascade="all-delete-orphan" />
    <property name="CultureCode" column="LanguageCode" 
              not-null="true" index="UQ_ProductTranslation" />
    <property name="Name" column="Name" not-null="true" />
  </class>

我的猜测是问题出在NHibernate的配置中。因为我可以在整个代码中跟随产品的创建。我也把show_sql打开了,它显示了Product的创建,但它没有ProductTranslations的插入。

INSERT INTO dbo.Product (SomeOtherStuff) VALUES (@p0); 
 select SCOPE_IDENTITY(); @p) = 'Hello this is a test' [Type: String (4000)]

1 个答案:

答案 0 :(得分:0)

上述映射应该有效。它只会生成并不总是想要的SQL语句。

  1. 插入父产品
  2. 插入子表ProductTranslation,而不参考产品表ProductId列必须可为空)
  3. 使用ProductId引用
  4. 更新子表

    所以,这个有点复杂的SQL语句甚至可以用于这种C#赋值

    var p = new Product();
    var tr1 = new ProductTranslation();
    var tr2 = new ProductTranslation();
    p.NaamTranslations.Add(tr1);
    p.NaamTranslations.Add(tr2);
    
    session.Save(p);
    

    为了避免这些插入和更新,并且只有一个INSERT,我们可以使用 inverse 映射。那将是这样的

    <class name="Product" table="Product">
        ...
        <set name="NaamTranslations" cascade="all" inverse="true">
    

    但现在我们必须在C#中设置引用的两边

    var p = new Product();
    var tr1 = new ProductTranslation();
    var tr2 = new ProductTranslation();
    p.NaamTranslations.Add(tr1);
    p.NaamTranslations.Add(tr2);
    
    // too soon - relation back to product is missing
    //session.Save(p);
    
    // assign reference 
    tr1.Product = p;
    tr2.Product = p;
    // now cascade will work
    session.Save(p);
    

    NHibernate现在:

    1. 插入父级
    2. 将完整记录插入儿童(稍后不再更新)