【问题标题】:Fluent-NHibernate Multi-Level Inheritance based on another columnFluent-NHibernate 基于另一列的多级继承
【发布时间】:2013-11-20 20:53:44
【问题描述】:

我在为我遇到的问题寻找好的文档时遇到问题。我正在重构企业解决方案的一部分,并将 NHibernate 换成我们的 ORM。我有 3 个表,我希望它们都相互继承。

MasterAccount:帐户:InvBilling

**MasterAccount**
id_MasterAccount

**Account**
id_Account
id_MasterAccount
id_InvBilling

**InvBilling**
id_InvBilling
id_MasterAccount

对于 MasterAccount 中的每一行,Account 中存在一行,其中 Id_MasterAccount 列相等,IsMaster 列为 1。但是,Account 表中还有其他记录,它们的 id_MasterAccounts 也等于与其父帐户相关联.最后,Account 表中的每条记录在 InvBilling 表中都有一条记录。

我在设置他们的映射时遇到了很多问题。关于如何设置的任何帮助?

我需要以某种方式告诉 MasterAccount 它应该将自己关联到哪个 Account 记录以及它应该使用的列。

编辑:这是我目前所拥有的:

public class MasterAccountEntity : AccountEntity{
    protected virtual int MAId {get;set;}
}

public class AccountEntity : InvBillingEntity{
    protected virtual int AId {get;set;}
    public virtual MasterAccountEntity MA {get;set;}
    public virtual InvBillingEntity IB {get;set;}
    public virtual bool IsMaster {get;set;}
}

public class InvBilling{
    protected virtual int IBId {get;set;}
    public MasterAccountEntity MA {get;set;}
}

然后对于我的映射(在如何显示继承方面有些迷失):

public class FluentHibernateMap : SubclassMap<MasterAccountEntity>{
    Table("MasterAccount");
    Map(x => x.MAId).Column("id_MasterAccount");
}

public class FluentHibernateMap : SubclassMap<AccountEntity>{
    Table("Account");
    Map(x => x.AId).Column("id_Account");
    Map(x => x.IsMaster).Column("isMaster");
    References(x => x.MA).Column("id_MasterAccount").Not.Nullable().Cascade.None();
    References(x => x.IB).Column("id_InvBilling").Not.Nullable().Cascade.None();
}

public class FluentHibernateMap : ClassMap<InvBillingEntity>{
    Table("InvBilling");
    Id(x => x.IBId).Column("id_InvBilling");
    References(x => x.MA).Column("id_MasterAccount").Not.Nullable().Cascade.None();
}

所以MasterAccount需要从Account继承IsMaster为true的记录,然后继承InvBilling中与Account中InvBillingId对应的记录。

【问题讨论】:

  • 要获得帮助,请发布您目前拥有的映射/实体代码
  • 添加了我的,希望你能帮上忙!

标签: inheritance fluent-nhibernate


【解决方案1】:

帐户表是一个版本控制表,它实际上是主表的多面。我会反映这一点,而不是试图在映射中隐藏它。那么对于历史记录和复杂性的上升,没有必要做任何事情都是不可能的。

public class Entity
{
    protected virtual int Id { get; private set; }  // should be readonly once set by NHibernate
}

public class AccountMasterEntry : Entity
{
    public virtual Account ActiveAccount { get; private set;}
}

public class Account : Entity
{
    public virtual AccountMasterEntry MA {get;set;}
    public virtual InvBillingEntity IB {get;set;}
    public virtual bool Active {get;set;}
}

public class InvBilling : Entity
{
}

public class AccountMasterEntryMap : ClassMap<AccountMasterEntry>
{
    public AccountMasterEntryMap()
    {
        Id(x => x.Id).GeneratedBy...;

        // optional
        References(x => x.ActiveAccount).Formula("(SELECT acc.id_Account FROM Account acc WHERE id_MasterAccount = acc.id_MasterAccount AND acc.IsMaster = 1)");
    }
}

public class AccountMap : ClassMap<Account>
{
    public AccountMap()
    {
        Id(x => x.Id).GeneratedBy...;

        References(x => x.MA, "id_MasterAccount");
        References(x => x.IB, "id_InvBilling");
        Map(x => x.Active, "ismaster");
    }
    public virtual AccountMasterEntry MA { get; set; }
    public virtual InvBilling IB {get;set;}
    public virtual bool IsMaster {get;set;}
}

public class InvBilling : Entity
{
}

// query
int masterId = ...;
var accountrecord = session.Query<Account>()
    .Where(a => a.MA.Id == masterId && a.Active)  // NHibernate should be smart enough to see that there is no join needed
    .Single();

注意:我不确定单独的 invbillingId 是唯一的还是复合 ID

【讨论】:

  • 这个答案会起作用,并且是我们最终最终要做的事情。然而,最初的想法是使用继承,这样您就可以创建一个主记录并通过执行 master.XXX 来引用它的 InvBilling 属性。尽管如此,我还是找不到根据 IsMaster 之类的属性来区分继承,所以我最终做了类似于你在答案中所做的事情。您完美地回答了我的评论,但这与这个问题的含义略有不同。 (我已经在这个问题上工作了几天,并发表了一些关于它的帖子)
  • 我想说的是,你不应该试图隐藏它来使用master.XXX,因为泄漏抽象的法则会为此困扰你。可以用公式进行区分,但我强烈反对这样做
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
相关资源
最近更新 更多