使用 Fluent NHibernate AutoMapping 进行级联保存

Posted

技术标签:

【中文标题】使用 Fluent NHibernate AutoMapping 进行级联保存【英文标题】:Cascade Saves with Fluent NHibernate AutoMapping 【发布时间】:2010-10-09 20:52:17 【问题描述】:

如何使用带有 Fluent NHibernate 的 AutoMap 持久性模型“打开”级联保存?

如:

我救了人,胳膊也应该救了。目前我得到

“对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例”

public class Person : DomainEntity

  public virtual Arm LeftArm  get; set; 


public class Arm : DomainEntity

  public virtual int Size  get; set; 

我找到了an article on this topic,但它似乎已经过时了。

【问题讨论】:

这会使用约定来完成吗? 【参考方案1】:

这适用于新的配置位。欲了解更多信息,请参阅http://fluentnhibernate.wikia.com/wiki/Converting_to_new_style_conventions

//hanging off of AutoPersistenceModel    
.ConventionDiscovery.AddFromAssemblyOf<CascadeAll>()


public class CascadeAll : IHasOneConvention, IHasManyConvention, IReferenceConvention

    public bool Accept( IOneToOnePart target )
    
        return true;
    

    public void Apply( IOneToOnePart target )
    
        target.Cascade.All();
    

    public bool Accept( IOneToManyPart target )
    
        return true;
    

    public void Apply( IOneToManyPart target )
    
        target.Cascade.All();
    

    public bool Accept( IManyToOnePart target )
    
        return true;
    

    public void Apply( IManyToOnePart target )
    
        target.Cascade.All();
    

【讨论】:

谢谢。我实际上使用了 Kristoffers 较短的示例,但我相信这个也可以使用【参考方案2】:

更新为与当前版本一起使用:

public class CascadeAll : IHasOneConvention, IHasManyConvention, IReferenceConvention

    public void Apply(IOneToOneInstance instance)
    
        instance.Cascade.All();
    

    public void Apply(IOneToManyCollectionInstance instance)
    
        instance.Cascade.All();
    

    public void Apply(IManyToOneInstance instance)
    
        instance.Cascade.All();
    

【讨论】:

对于“public void Apply(IOneToManyCollectionInstance instance)”,我也发现使用“instance.inverse();”很有用除了“instance.Cascade.All()”。【参考方案3】:

我发现对整个项目执行此操作的最简单方法是使用 DefaultCascade

.Conventions.Add( DefaultCascade.All() );     

转到 wiki 上的 "The Simplest Conventions" 部分,查看此内容以及其他列表。

这是来自 Wiki 的列表:

Table.Is(x => x.EntityType.Name + "Table")
PrimaryKey.Name.Is(x => "ID")
AutoImport.Never()
DefaultAccess.Field()
DefaultCascade.All()
DefaultLazy.Always()
DynamicInsert.AlwaysTrue()
DynamicUpdate.AlwaysTrue()
OptimisticLock.Is(x => x.Dirty())
Cache.Is(x => x.AsReadOnly())
ForeignKey.EndsWith("ID")

警告 - Wiki 中的某些方法名称可能是错误的。我用我可以验证的内容(即 DefaultCascade 和 DefaultLazy)编辑了 Wiki,但不能保证其余部分。但是,如果需要,您应该能够使用 Intellisense 找出正确的名称。

【讨论】:

我很想看到那个链接,但它已经死了 @Joel:看起来新的 wiki 在这里:github.com/jagregory/fluent-nhibernate/wiki/Conventions【参考方案4】:

约定方法签名已更改。有关完全符合此问题要求的新答案,请参阅THIS QUESTION。

【讨论】:

【参考方案5】:

您还可以将级联设为所有类型的默认约定。例如(使用您链接到的文章作为起点):

autoMappings.WithConvention(c =>  
    
    // our conventions
    c.OneToOneConvention = o => o.Cascade.All();
    c.OneToManyConvention = o => o.Cascade.All();
    c.ManyToOneConvention = o => o.Cascade.All();
  );

【讨论】:

以上是关于使用 Fluent NHibernate AutoMapping 进行级联保存的主要内容,如果未能解决你的问题,请参考以下文章

使用 Fluent NHibernate 和 NHibernate 3 将枚举映射为 Int

Fluent 映射和 NHibernate Xml 配置

NHibernate 2 + Fluent Nhibernate 中等信任

使用 Fluent NHibernate 映射泛型类

在使用fluent-nhibernate配置nhibernate时,为什么会出现MissingMethodException?

使用 2 种策略通过 fluent nhibernate 映射类层次结构