我正在构建一个多语言应用程序,其中包含一些动态翻译。因此,我选择为产品制作单独的表格,其中包括翻译。
不,我无法插入翻译,它们是产品的一部分。插入哪个。
<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,它显示了产品的创建,但缺少 ProductTranslations 的插入。
INSERT INTO dbo.Product (SomeOtherStuff) VALUES (@p0);
select SCOPE_IDENTITY(); @p) = 'Hello this is a test' [Type: String (4000)]
最佳答案
上面的映射应该是有效的。它只会生成并不总是需要的 SQL 语句。
- 插入父产品
- 插入子表
ProductTranslation
,不引用 Product 表(ProductId
列必须可以为空) - 使用
ProductId
reference 更新子表
所以,即使对于这种 C# 赋值,这种有点复杂的 SQL 语句也可以工作
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 现在将:
- 插入父级
- 将完整记录插入子项(以后不再更新)
关于c# - NHibernate 不插入 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36939160/