5

我必须在 NHibernate 中对这种关系进行建模(稍微简化代码以保持主题) - 员工可以是帐户经理(因此,它是可选的):

表 Employee (Id, Number, Name) 表 EmployeeIsAccountManager (Number, MaxAllowedDiscount)

我没有在 EmployeeIsAccountManager 表中有一个 Id 外键指向表 Employee,而是在 Employee 表中有一个 Number 列,它指向 EmployeeIsAccountManager 表中的 Number 列。

我如何在 NHibernate 中映射它?我尝试在 EmployeeIsAccountManager 类映射上使用外部生成器,但如果我使用 Number 作为外部生成值,它会映射到 Employee 的 ID,它是 Id 而不是 Number。我为我的班级建模以使用组合:

public class Employee
{
   public virtual int Id { get; set; }
   public virtual short Number {get; set; }
   public virtual string Name {get; set; }
   public virtual AccountManager AccountManager { get; set; }
}

public class AccountManager
{
  public virtual short Number { get; set; } /*needed because of ID only?*/
  public virtual decimal MaxAllowedDiscount { get; set }
}   

我已经尝试了很多(一对一、多对一、外国生成器),但我不知道这是否可以用 NHibernate 完成。顺便说一句:我可以更改类、映射等,但我不能更改表结构,因为它是棕地状态(旧应用程序有 2+ 百万行代码,近 1000 个表格)。

任何帮助表示赞赏,谢谢!泰德

4

2 回答 2

0

你的问题让我想到了类继承,你可以将你的类 AccountManager 映射为 Employee 的子类,然后你就可以做你想做的事情,我已经为你测试了一个映射,但是当你以这种方式设计表格时不会解决您的需求,因为您必须在映射中注意两点:

  1. Employee 表中的 number 属性应该是 AccountManager 的一种独特的外键,以便用作外键,但即使这样它也不起作用,因为 NHibernate,当您尝试插入新的 Account Manager 时会插入一条记录在 person 表中,然后将 person 的 id 分配给 AccountManager 的 number 列,这是您需要的。
  2. 出于同样的原因,将该关系映射为多对一并不起作用。AccountManager 的 Number 属性是主键吗?是独特的?NHibernate 不能在没有主键的情况下工作,因此为了使这种关系起作用,您必须将 AccountManager 的 Number 属性指定为 Id 列

我想到的最后一个选项是使用映射到 AccountManager 表的 Employee 类中的属性,其中您可以指定自定义选择以获得所需的值我假设属性 MaxAllowedDiscount,但这也有一些限制,当你用公式映射一个属性时,这个属性不能插入也不能更新。

如果有问题,希望这对我有帮助。

于 2011-02-28T14:13:40.167 回答
0
public class Employee
{
    public virtual short Number
    {
       get { return (AccountManager == null) ? 0 : AccountManager.Number; }
       set
       {
           if (AccountManager == null)
               AccountManager = new AccountManager();
           AccountManager.Number = value;
       }
    }
    public virtual AccountManager AccountManager { get; set; }
}

或使用 GeneratedBy.Assinged()

public class Employee
{
    public Employee()
    {
        AccountManager = new AccountManager();
    }

    public virtual AccountManager AccountManager
    {
        get;
        set { value.Parent = this; _accountManager = value; }
    }

    public class AccountManager
    {
        Internal protected virtual Employee Parent { get; set; } 

        protected virtual short Number { get { return Parent.Number; } set { } } /*needed because of ID only?*/
        public virtual decimal MaxAllowedDiscount { get; set }
    }
}
于 2011-11-25T16:04:38.753 回答