使用错误(棕地)数据库模式映射一对一关系

发布于 2024-10-06 06:37:07 字数 1008 浏览 2 评论 0原文

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

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

不是在表 EmployeeIsAccountManager 中有一个指向表 Employee 的 Id 外键,而是在 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 个表单的旧应用程序)。

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

I have to model this relationship in NHibernate (simplified the code a bit to stay on-topic) - an employee can be an accountmanager (so, it's optional):

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

instead of having an Id foreign key in table EmployeeIsAccountManager pointing to table Employee, I have a Number column in the Employee table which points to the Number column in table EmployeeIsAccountManager.

How do I map this in NHibernate? I've tried using the foreign generator on the EmployeeIsAccountManager class mapping, but if I use Number as foreign generated value, it maps to the ID of Employee, which is Id instead of Number. I modeled my class to use composition:

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 }
}   

I've tried a lot (one-to-one, many-to-one, foreign generator) but I can't figure out if this can be done with NHibernate. btw: I can change the classes, mappings, etc but I CANNOT change the table structure because of it's brownfield status (old application with 2+ million lines of code, nearly 1000 forms).

Any help is appreciated, thanks!
Ted

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

街角迷惘 2024-10-13 06:37:07

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

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

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

希望这有帮助
如果有问题请告诉我。

Your question make me think about class inheritance, you could map your class AccountManager as a subclass of Employee and then you will able to do what you want to do, I'v etested a mapping for you but as you designed tables that way does not resolve your needs because there are two points you have to notice in your mapping:

  1. The number property in the Employee table should be a unique kind of foreing key to AccountManager in order to be used as a foreign key but even so it does'mt work because NHibernate, when you try to insert a new Account Manager will insert a record in the person table and then assign the id of person to the number column of AccountManager an that break you needs.
  2. Mapping that relation as many-to-one doesn't work for the same reason. The Number property of AccountManager is primary key? is unique? NHibernate cannot work without primary keys, so in order to make that relation to work you have to specify the Number propety of AccountManager as an Id column

The last option which comes in my mind is to use a property in the Employee class mapped
to the AccountManager table with a formula where you can specify a custom select to obtain the value you need I assume the property MaxAllowedDiscount, but this too has some limitation, when you map a property with formula, this property cannot be inserted nor updated.

Hope this helps
lat me konw if there are questions.

疧_╮線 2024-10-13 06:37:07
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; }
}

或使用GenerateBy.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 }
    }
}
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; }
}

or with 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 }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文