我对配置NHibernate相对较新,并遇到了问题。我有以下实体:
public class Report
{
public virtual int Id { get; private set; }
public virtual string Name { get; private set; }
public virtual string Path { get; private set; }
public virtual string Alias { get; private set;}
public virtual IList<Tab> Tabs
{
get; private set;
}
}
public class Tab
{
public virtual string Name { get; private set; }
public virtual string Description { get; private set; }
public virtual IList<Section> Sections { get; set; }
public virtual Report ParentReport { get; private set; }
}
public class Section
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
我使用Fluent NHibernate和Auto Mapping来映射关系。
.Database(MsSqlConfiguration.MsSql2005.ShowSql().ConnectionString(c => c.Is(connectionString)))
.Mappings(map => map.AutoMappings.Add(AutoMap.AssemblyOf<Workbook>(configuration)
.Conventions.AddFromAssemblyOf<CascadeAll>()
问题在于,无论我在CascadeAll类中选择哪种级联选项,我都无法按照我的意愿执行它。
当我从给定报表中删除Tab时,我希望从数据库中删除选项卡上的部分,然后从数据库中的报表中删除选项卡。
Cascade.All()
删除Report和Tab之间的关系,但将选项卡设置ParentReport_id孤立为null。
Cascade.AllDeleteOrphan()
这将删除与报告关联的所有部分,选项卡,然后删除报告,尽管只从报告中的集合中删除一个选项卡。
Cascade.SaveUpdate()
像All一样的行为,或者选择标签。
顺便提一下,这些都是通过从Report上的选项卡集合中删除选项卡然后调用session.SaveUpdate(instance)&gt;来调用的。其中实例是正在更新的报表实例。
我知道如何解决这个或我做错了什么?
答案 0 :(得分:1)
感谢雷克斯,我怀疑你的建议会有用,所以我可以尝试一下。这完全取决于Report和Tab之间的关系,导致OneToMany(Report-&gt; Tab)和ManyToOne(Tab-&gt; Report)。使用我选择的级联选项,它可以是NUll外键,也可以删除选项卡,所有其他选项卡和报告。这与AllDeleteOrphan有关。
当我删除标签时 - &gt;报告ManyToOne关系孤立记录被删除没有删除Repotr。最后,我快速选择创建一个显式映射文件,该文件在ReportMapping文件中使用HasMany(x =&gt; x.Tabs).... TabMapping上的引用(x =&gt; x.ParentReport)...
感谢您的帮助。
答案 1 :(得分:0)
听起来你需要结合使用这些。当您需要除惯例提供的默认值以外的其他内容时,您可以为特殊情况编写overrides。
如果你的覆盖中出现的模式在大多数情况下都是正确的,你可以创建一个新的约定来处理它,而不是每次都要指定覆盖。
我相信您希望.AllDeleteOrphan()
用于Sections
收藏,并使用.All()
收集Tabs
收藏。
在您的情况下,我相信您的覆盖会看起来像这样。
public class ReportMappingOverride : IAutoMappingOverride<Report>
{
public void Override(AutoMapping<Report> mapping)
{
// You don't need this, but I'll leave it for an example...
//mapping.HasMany(x => x.Tabs).Cascade.All();
}
}
public class TabMappingOverride : IAutoMappingOverride<Tab>
{
public void Override(AutoMapping<Tab> mapping)
{
// You don't need this, but I'll leave it for an example...
//mapping.HasMany(x => x.Sections).Cascade.AllDeleteOrphan();
// This should prevent deletes from being cascaded to the Report
// (which would delete the report).
mapping.References(x => x.ParentReport).Cascade.SaveUpdate();
}
}
要使用覆盖,您的配置会稍微改变一下,看起来像这样。
.Mappings(map => map.AutoMappings.Add(AutoMap.AssemblyOf<Workbook>(configuration).UseOverridesFromAssemblyOf<ReportMappingOverride>()
将属性返回到父报告无关紧要,但是为了进行测试,您可以将其取出并查看是否存在问题。