NHibernate继承从父级创建子对象

时间:2013-10-15 13:51:57

标签: c# oop nhibernate inheritance fluent-nhibernate

如果这是一个愚蠢的问题,我很抱歉,但我似乎无法控制住。

我有2个课程,CustomerMember

Customer.cs

public class Customer
{
    public virtual string Firstname { get; set; }
    public virtual string Middlename { get; set; }
    public virtual string Lastname { get; set; }
}

Member.cs

public class Member : Customer
{
    public virtual string MemberId { get; set; }
    public virtual string MemberRegistrationDate { get; set; }
    public virtual string MembershipStatus { get; set; }

    public Member()
    {
        MemberRegistrationDate = DateTime.Now;
        MembershipStatus = MembershipStatusEnum.Active;
    }
}

我很确定这必须是一个继承,其中会员客户,但如果我绝望,我可以求助于撰写。

请注意,我在这里使用的NHibernate迫使我使用所有虚拟内容。

鉴于单个客户对象,现有客户的新成员应该如何?

我可以在这里考虑两个选项:

1 - 使用Member.cs构造函数重新创建它的父属性

这是一件好事吗?我试着这样做:

public class Member : Customer
{
    public virtual string MemberId { get; set; }
    public virtual string MemberRegistrationDate { get; set; }
    public virtual string MembershipStatus { get; set; }

    public Member(Customer customer)
    {
       Firstname = customer.Firstname;
       Middlename = customer.Middlename;
       Lastname = customer.Lastname;

       MemberRegistrationDate = DateTime.Now;
       MembershipStatus = MembershipStatusEnum.Active;
    }
}

但Resharper警告我在构造函数中访问虚拟成员,我同意避免,并告诉我使成员成为一个无法拥有虚拟成员的密封类(没有NHibernate兼容性)。

当有一天我向Customer类添加了一个新属性时,它也引发了另一个问题,我忘了对Member构造函数做同样的事情。

2 - 使用某种反射助手在两个对象之间进行映射。

当然这是一个可行的选择,但我目前正在学习DDD,我想知道是否可以将这样的帮助器放在域层中?

需要一些建议,谢谢!

1 个答案:

答案 0 :(得分:1)

不确定我是否帮助您,但您无需在Customer课程中执行任何与Member相关的操作。您只需告诉NHibernate该Member派生自Customer,您需要为这两个类提供正确的映射。就是这样,其余部分自动完成(无论如何,这是OOP中的整个继承点)。

关于你的第二个问题('不要在c'tor中调用虚拟'。):这在理论上是正确的,但只有在有可能虚拟方法在派生类中被覆盖时才有意义。所以你可以在这里安全地忽略R#警告。

但是我认为这里最简单的方法是完全摆脱会员的责任并宣布这样的课程如下:

public class Member : Customer
{
    private memberRegistrationDate = DateTime.Now;
    private membershipStatus = MembershipStatusEnum.Active;

    public virtual string MemberId { get; set; }
    public virtual string MemberRegistrationDate 
    { 
      get { return this.memberRegistrationDate; }; 
      set { this.memberRegistrationDate = value; }; 
    }
    public virtual string MembershipStatus 
    { 
      get { return this.membershipStatus; }; 
      set { this.membershipStatus = value; }; 
    }
}

修改: 如果您正在寻找一种简单的方法将客户转变为会员,您应该完全保留转换代码,而不是将其转换为扩展方法(以保持清洁):

public static class CustomerExtensions
{
    public static Member ToMember(this Customer customer)
    {
        var member = new Member();
        member.Firstname = customer.Firstname;
        member.Middlename = customer.Middlename;
        member.Lastname = customer.Lastname;

        return member;
    }
}

你可以这样打电话:

Member member = customer.ToMember();