流利的NHibernate Child集合持久性问题 [英] Fluent NHibernate Child collection persistence issues

查看:107
本文介绍了流利的NHibernate Child集合持久性问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public class CardTemplateMapping:ClassMap< CardTemplate> 
{
public CardTemplateMapping()
{
表(cardtemplate);

Id(x => x.Id)
.Column(id)
.GeneratedBy.Native();

HasMany(x => x.CostStructures)
.KeyColumn(cardtemplate_id)
.Cascade.All();

}
}
公共类CostStructureMapping:ClassMap< CostStructure>
{
public CostStructureMapping()
{
表(costtructure);

Id(x => x.Id)
.Column(id)
.GeneratedBy.Native();

引用(x => x.CardTemplate)
.Column(cardtemplate_id);

HasMany(x => x.CostComponents)
.KeyColumn(costtructure_id)
.Cascade.AllDeleteOrphan();



公共类CostStructureComponentMapping:ClassMap< CostStructureComponent>
{
public CostStructureComponentMapping()
{
表(CostStructureComponent);

Id(x => x.Id)
.Column(id)
.GeneratedBy.Native();

引用(x => x.CostStructure)
.Column(costtructure_id);

引用(x => x.ResourceType)
.Column(resourcetype_id);






$ b

Nhibernate按照我的意图加载关系。但是映射的两个部分看起来有些奇怪(或者说,或者我的期望是奇怪的)。
$ b $首先:


pre> CostStructure structure = new CostStructure(){CardTemplate = template};
template.CostStructures.Add(structure);
Session.Save(template);
Session.Flush();

这不会保存新的 CostStructure 实例。为什么?第二个:假设我已经加载了一个 CardTemplate ,其中有一个 CostStructure code>包含三个 CostStructureComponent 个实体。现在我想从 CostStructure 中删除​​ CostStructureComponents 之一。

我试过以下:

  costStructure.CostComponents.Remove(component); 
component.CostStructure = null;
session.Save(template)

现在,我知道显式删除显式的作品,但不应该 DeleteOrphan 部分也声明现在没有 CostStructure 引用的组件被删除? NHibernate尝试执行以下更新:

pre $ UPDATE CostStructureComponent $ b $ SET金额= @ p0,
coststructure_id = @ p1,
resourcetype_id = @ p2
WHERE id = @ p3;
$ b @ p0 = 1 [类型:Int32(0)],
@ p1 = NULL [类型:Int64(0)],
@ p2 = 5 [类型:Int64 (0)],
@ p3 = 13 [类型:Int64(0)]

难道是Equals / GetHashCode已经被错误地执行了?



对不起,已经很晚了,漫长的一天等等...如果我说的是乱码,请让我知道...

解决方案

所有答案都隐藏在一个设置 .Inverse()

  public CardTemplateMapping()
{
HasMany(x => x.CostStructures)
.KeyColumn(cardtemplate_id)
.Cascade.All()
.Inverse(); //这里是这个设置

在这里:

< pre $ public CostStructureMapping()
{
..
HasMany(x => x.CostComponents)
.KeyColumn(costtructure_id )
.Cascade.AllDeleteOrphan()
.Inverse(); //和HERE以及HasMany()上的所有地方(

尝试查找关于此设置的一些文章,一般:如果映射为逆,NHibernate准备好做更好的SQL语句,因为它正在处理关系的另一端...



一些来源:



19.5.2 。列表,地图,idbags和集合是最有效的集合更新 然而, b


在精心设计的NHibernate领域模型中,我们经常看到大多数集合实际上是一对多 (评论:流利中的HasMany) inverse =true 的关联。对于这些关联,更新由关联的多对一 (注释:Fluent中的引用)结尾进行处理,因此注意事项收集更新性能根本不适用。

6.2。映射集合


反向 (可选 - 默认为false)将此集合标记为双向关联的反向结尾



I have the following mapping classes (only the relevant part copied):

public class CardTemplateMapping : ClassMap<CardTemplate>
{
    public CardTemplateMapping()
    {
        Table("cardtemplate");

        Id(x => x.Id)
            .Column("id")
            .GeneratedBy.Native();

        HasMany(x => x.CostStructures)
            .KeyColumn("cardtemplate_id")
            .Cascade.All();

    }
}
public class CostStructureMapping : ClassMap<CostStructure>
{
    public CostStructureMapping()
    {
        Table("coststructure");

        Id(x => x.Id)
            .Column("id")
            .GeneratedBy.Native();

        References(x => x.CardTemplate)
            .Column("cardtemplate_id");

        HasMany(x => x.CostComponents)
            .KeyColumn("coststructure_id")
            .Cascade.AllDeleteOrphan();

    }
}
public class CostStructureComponentMapping : ClassMap<CostStructureComponent>
{
    public CostStructureComponentMapping()
    {
        Table("CostStructureComponent");

        Id(x => x.Id)
            .Column("id")
            .GeneratedBy.Native();

        References(x => x.CostStructure)
            .Column("coststructure_id");

        References(x => x.ResourceType)
            .Column("resourcetype_id");
    }
}

Nhibernate loads the relations as I intended. But two parts of the Mapping seem a bit weird (either that or my expectations are weird).

First:

 CostStructure structure = new CostStructure() { CardTemplate = template };
 template.CostStructures.Add(structure);
 Session.Save(template);
 Session.Flush();

This does not save the new CostStructure instance. Why?

Second one: Assuming I have loaded a CardTemplate having a CostStructure containing three CostStructureComponent entities. Now I want to remove one of those CostStructureComponents from the CostStructure.
I tried the following :

costStructure.CostComponents.Remove(component);
component.CostStructure = null;
session.Save(template)

Now, I know that explicitly deleting explicitly works, but shouldn't the DeleteOrphan part also assert that the component, now without CostStructure to reference, is deleted? Instead, NHibernate tries to perform the following update:

UPDATE CostStructureComponent 
SET amount = @p0, 
     coststructure_id = @p1, 
     resourcetype_id = @p2
WHERE id = @p3;

@p0 = 1 [Type: Int32 (0)], 
@p1 = NULL [Type: Int64 (0)], 
@p2 = 5 [Type: Int64 (0)], 
@p3 = 13 [Type: Int64 (0)]

Could it be Equals / GetHashCode have been implemented the wrong way?

Sorry, it's late, been a long day and so forth...If I'm talking gibberish, please let me know...

解决方案

All the answers are hidden in one setting .Inverse()

public CardTemplateMapping()
{
    HasMany(x => x.CostStructures)
        .KeyColumn("cardtemplate_id")
        .Cascade.All()
        .Inverse(); // HERE this setting

And here:

public CostStructureMapping()
{
    ..
    HasMany(x => x.CostComponents)
        .KeyColumn("coststructure_id")
        .Cascade.AllDeleteOrphan()
        .Inverse();  // and HERE and everywhere on HasMany()

Try to find some articles about this setting, but in general: If mapped as inverse, NHibernate is ready to do much better SQL Statements, because it is working with other end of relation...

Some sources:

19.5.2. Lists, maps, idbags and sets are the most efficient collections to update cite:

However, in well-designed NHibernate domain models, we usually see that most collections are in fact one-to-many (comment: HasMany in Fluent) associations with inverse="true". For these associations, the update is handled by the many-to-one (comment: References in Fluent) end of the association, and so considerations of collection update performance simply do not apply.

6.2. Mapping a Collection

inverse (optional - defaults to false) mark this collection as the "inverse" end of a bidirectional association

这篇关于流利的NHibernate Child集合持久性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆