Сопоставление различных столбцов внешнего ключа на основе родительского типа во время выполнения - PullRequest
2 голосов
/ 16 марта 2010

Я думаю, что, вероятно, знаю, что наиболее распространенным предложением будет «изменить схему базы данных», но, к сожалению, это одна из тех ситуаций, когда «я застрял с устаревшей базой данных».

В основном я хочу сопоставитьследующее с использованием Fluent NHibernate

CREATE TABLE Person (PersonId int)
CREATE TABLE Organisation (OrganisationId int)
CREATE TABLE OwnedPhoneNumber (Id int, PersonId int, OrganisationId int, 
PhoneNumber varchar(50))

interface IPhoneNumberOwner
{
    int Id {get; set;}
}
class Person : IPhoneNumberOwner
{
  public virtual int Id {get; set;}
  public virtual ISet<OwnedPhoneNumber> PhoneNumbers {get; set;}
}
class Organisation : IPhoneNumberOwner
{
  public virtual int Id {get; set;}
  public virtual ISet<OwnedPhoneNumber> PhoneNumbers {get; set;}
}
class OwnedPhoneNumber
{
  public virtual int Id {get; set;}
  public virtual IPhoneNumberOwner Owner {get; set;}
  public virtual string PhoneNumber {get; set;}
}

Мой вопрос заключается в том, как создать файл ClassMap для класса OwnedPhoneNumber, чтобы определить столбец для использования при сохранении сущности, т. е. если это объект Person, используйте столбец PersonId и еслиэто организация, использующая столбец OrganisationId.Сопоставление коллекций из родительских классов не является проблемой.

Надеюсь, я включил достаточно подробностей, чтобы объяснить проблему, но, конечно, выкрикните, если нет.

1 Ответ

0 голосов
/ 26 марта 2010

Обратите внимание на это, если кто-то сталкивается с той же проблемой, но я нашел обходной путь, который некоторым может понравиться (а кому-то нет). После нескольких не очень полезных ответов я пришел к выводу, что (оставив в стороне обсуждение схемы базы данных) это невозможно сделать с помощью nhibernate. Поэтому я решил создать два представления в базе данных и представить их в виде таблиц для nhibernate в отображении. т.е.

CREATE VIEW dbo.vw_PersonPhoneNumber
AS
SELECT  pn.Id,
    pn.PersonId,
    pn.PhoneNumber
FROM    dbo.PhoneNumber pn INNER JOIN dbo.Person o ON pn.PersonId = o.PersonId

и

CREATE VIEW dbo.vw_OrganisationPhoneNumber
AS
SELECT  pn.Id,
    pn.OrganisationId,
    pn.PhoneNumber
FROM    dbo.PhoneNumber pn INNER JOIN dbo.Organisation o ON pn.OrganistionId = o.OrganisationId

Использование этих представлений в отображении, как если бы они были таблицами, включает все обычные операции CRUD при поддержании исходной схемы, хотя и с двумя дополнительными представлениями.

Конечно, это компромисс, но я думаю, что он оправдан, если вы не можете изменить структуру таблицы в существующей базе данных.

...