Fluent NHibernate 在插入复合键后执行更新

发布于 2024-10-10 14:12:24 字数 2364 浏览 11 评论 0原文

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

实体关系如下:

1)模型(父)- 有许多 FactorWeights。
2) FactorWeight (子) 有一个 Factor。
3) 每个模型的因素可以有不同的权重。

由于模型有很多Factor,并且不同模型的Factor可以有不同的权重,因此FactorWeight实体需要具有ModelID和FactorID的组合键。

模型:

    public virtual int ID { get; set; }  
    public virtual IList<FactorWeight> FactorWeights { get; set; }  
    public virtual string Name { get; set; }    

Factor:

    public virtual int ID { get; set; }  
    public virtual string Name { get; set; }  

FactorWeight:

    public virtual Factor Factor { get; set; }  
    public virtual Model Model { get; set; }  
    public virtual decimal Weight { get; set; }  

映射如下:

模型:

public void Override(AutoMapping<Model> mapping)
{
 mapping.Id(x => x.ID);
 mapping.Map(x => x.Name);

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

FactorWeights

public void Override(AutoMapping<FactorWeight> mapping)
{
 mapping.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 });

以下代码用于持久化实体(其中模型传递给方法):

public void CreateEntity(object entity)
{
 HibernateConfiguration.Session.Transaction.Begin();
 NHibernateConfiguration.Session.Save(entity);   
 NHibernateConfiguration.Session.Transaction.Commit();
}

Model实体以及 FactorWeight 均已正确保存。问题在于 SQL Profiler 在插入后立即显示 FactorWeight.ModelID 列的更新。 NHibernate 使用插入中已存在的新插入的 ModelID 更新 FactorWeight.ModelID。

SQl Profiler Trace:

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 版本。

谢谢。

I am using Fluent NHibernate to map a composite key. I need the child entity to receive the newly inserted parent key when the parent is created. This works but NHibernate is doing an insert on the child and thereafter doing an update on one of the composite key IDs on the child.

The entity relationships are as follows:

1) Model (parent) - has many FactorWeights.
2) FactorWeight (child) has one Factor.
3) Factors can have different weightings per model.

Since Models have many Factors and the Factor can have different weightings for different models, the FactorWeight entity is required with the composite key of ModelID and FactorID.

Model:

    public virtual int ID { get; set; }  
    public virtual IList<FactorWeight> FactorWeights { get; set; }  
    public virtual string Name { get; set; }    

Factor:

    public virtual int ID { get; set; }  
    public virtual string Name { get; set; }  

FactorWeight:

    public virtual Factor Factor { get; set; }  
    public virtual Model Model { get; set; }  
    public virtual decimal Weight { get; set; }  

The mappings are as follows:

Model:

public void Override(AutoMapping<Model> mapping)
{
 mapping.Id(x => x.ID);
 mapping.Map(x => x.Name);

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

FactorWeights

public void Override(AutoMapping<FactorWeight> mapping)
{
 mapping.CompositeId()
           .KeyReference(factorWeight => factorWeight.Model, "ModelID")
           .KeyReference(factorWeight => factorWeight.Factor, "FactorID");

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

I use the following code to create the FactorWeight within the Model object:

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

The following is used to persist the entity (where the model is passed to the method):

public void CreateEntity(object entity)
{
 HibernateConfiguration.Session.Transaction.Begin();
 NHibernateConfiguration.Session.Save(entity);   
 NHibernateConfiguration.Session.Transaction.Commit();
}

The Model entity is saved without an error as well as the FactorWeight. The problem is that SQL Profiler shows an update on the FactorWeight.ModelID column immediately after the insert. NHibernate updates the FactorWeight.ModelID with the newly inserted ModelID which was already present in the insert.

SQl Profiler Trace:

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

I assume this is a problem with the mapping of the composite key.

I am using version 2.1.2.400 of NHibernate and version 1.1.0.685 of FluentNHibernate.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

弥繁 2024-10-17 14:12:24

好吧,我想我需要提高我的谷歌搜索技能...在这里找到了答案:是否可以在 NHibernate 中抑制插入后的更新?

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

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

反向告诉父级,子级负责维护关系,从而防止额外的更新” - 来自上面的链接。

Ok, I think I need to improve my Googling skills...found the anwser here: Is it possible to suppress the Update after Insert in NHibernate?.

Turns out I needed to add Inverse() to the mapping on the parent. Added the following and problem solved:

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

"Inverse tells the parent that the child is responsible for maintaining the relationship thus preventing the extra update" - from link above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文