1

我正在使用 Fluent NHibernate 来映射复合键。我需要子实体在创建父实体时接收新插入的父密钥。这可行,但 NHibernate 正在对子项进行插入,然后对子项上的一个复合键 ID 进行更新。

实体关系如下:

1) Model (parent) - 有很多 FactorWeights。
2) FactorWeight (child) 有一个 Factor。
3) 每个模型的因素可以有不同的权重。

由于模型有许多因子,并且因子可以对不同的模型具有不同的权重,因此需要因子权重实体与模型ID 和因子ID 的复合键。

模型:

    公共虚拟整数 ID { 获取;放; }  
    公共虚拟 IList<FactorWeight> FactorWeights { get; 放; }  
    公共虚拟字符串名称 { 获取;放; }    

因素:

    公共虚拟整数 ID { 获取;放; }  
    公共虚拟字符串名称 { 获取;放; }  

因素权重:

    公共虚拟因子因子 { 得到;放; }  
    公共虚拟模型模型{获取;放; }  
    公共虚拟十进制权重{获取;放; }  

映射如下:

模型:

公共无效覆盖(AutoMapping<Model> 映射)
{
 映射.Id(x => x.ID);
 mapping.Map(x => x.Name);

 mapping.HasMany(x => x.FactorWeights)
    .KeyColumn("ModelID");
}

因子权重

公共无效覆盖(AutoMapping<FactorWeight> 映射)
{
 映射.CompositeId()
           .KeyReference(factorWeight => factorWeight.Model, "ModelID")
           .KeyReference(factorWeight => factorWeight.Factor, "FactorID");

 mapping.Map(factorWeight => factorWeight.Weight);
}

我使用以下代码在 Model 对象中创建 FactorWeight:

Model.FactorWeights.Add(new FactorWeight {Factor = factor, Weight = weighting, Model = Model });

以下用于持久化实体(将模型传递给方法):

公共无效创建实体(对象实体)
{
 HibernateConfiguration.Session.Transaction.Begin();
 NHibernateConfiguration.Session.Save(实体);   
 NHibernateConfiguration.Session.Transaction.Commit();
}

模型实体和 FactorWeight 都被正确保存。问题是 SQL Profiler 在插入后立即显示 FactorWeight.ModelID 列的更新。NHibernate 使用插入中已经存在的新插入的 ModelID 更新 FactorWeight.ModelID。

SQL Profiler 跟踪:

exec sp_executesql N'INSERT INTO [FactorWeight] (Weight, ModelID, FactorID) VALUES (@p0, @p1, @p2)',N'@p0 decimal(1,0),@p1 int,@p2 int',@ p0=1,@p1=56,@p2=1  
exec sp_executesql N'UPDATE [FactorWeight] SET ModelID = @p0 WHERE ModelID = @p1 AND FactorID = @p2',N'@p0 int,@p1 int,@p2 int',@p0=56,@p1=56, @p2=1

我认为这是复合键映射的问题。

我正在使用 NHibernate 的 2.1.2.400 版和 FluentNHibernate 的 1.1.0.685 版。

谢谢你。

4

1 回答 1

1

好的,我想我需要提高我的谷歌搜索技能......在这里找到了答案:Is it possible to suppress the Update after Insert in NHibernate? .

原来我需要将 Inverse() 添加到父级的映射中。添加了以下内容并解决了问题:

    mapping.HasMany(x => x.FactorWeights)
    .KeyColumn("ModelID")
    。逆();  

Inverse 告诉父母孩子负责维持关系,从而防止额外的更新” - 来自上面的链接。

于 2011-01-05T16:26:33.547 回答