NHibernate один вопрос, один ко многим, картографический вопрос - PullRequest
2 голосов
/ 09 февраля 2009

У меня есть сценарий в NHibernate, где у меня есть отношения один-ко-многим между сущностями Employee и EmployeeStatus.

Сотрудник имеет свойства, например: ID, Имя и IList EmployeeStatus, в то время как EmployeeStatus для целей этого вопроса просто имеет свой собственный идентификатор и некоторый свободный текст.

Мне не нужно хранить ссылку на Employee из EmployeeStatus, управление статусом будет осуществляться исключительно через сущность Employee - добавление к свойству IList. IE: я хочу просто быть в состоянии сделать следующее;

Employee e = new Employee();
e.Name = "Tony";
e.StatusList.Add( new EmployeeStatus("Status A") );
e.StatusList.Add( new EmployeeStatus("Status B") );
session.Save(e);

Я пробовал различные методы, в том числе создание одностороннего сопоставления один-ко-многим, когда обратное значение равно false, для каскада установлено значение all-delete-orphan, которое выглядит так, как будто оно должно работать, но при этом генерируется исключение невозможно установить EmployeeId в EmployeeStatus. Я склонен полагать, что это потому, что NHibernate хочет сделать вставку с EmployeeId как NULL, а затем обновить его до идентификатора родителя.

Я полагаю, что я что-то здесь упускаю, так просто - кто-нибудь может сказать мне, как должен выглядеть мой файл сопоставления для достижения вышеуказанного?

Заранее спасибо

Tony

- правка: Вот примерное представление о классах согласно запросу -

public class Employee
{
  private IList<EmployeeStatus> _statusList;

  public Employee()
  {
    _statusList = new List<EmployeeStatus>();
  }

  public virtual int Id{ get; set; }

  public virtual string Name{ get; set; }

  public virtual IList<EmployeeStatus> StatusList
  {
    get
    {
      return _statusList;
    }
  }
}

public class EmployeeStatus
{
  public virtual int Id{ get; set; }
  public virtual string StatusText{ get; set; }

  public EmployeeStatus()
  {
  }

  public EmployeeStatus(string statusText)
  {
    StatusText = statusText;
  }
}

Ответы [ 4 ]

2 голосов
/ 30 июля 2009

Сценарий, который вы описали, является просто базовым сопоставлением «один ко многим». Вот для этого карта Fluent NHibernate:

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        WithTable("Employee");
        HasMany(employee => employee.StatusList)
        .Cascade.All();
    }
}

Вам не нужно поддерживать ссылку EmployeeStatus на Employee для достижения этой цели.

0 голосов
/ 09 февраля 2009

Я не могу четко объяснить, но статус сотрудника не может быть связан более чем с одним сотрудником. Это определенно 1 (сотрудник) для многих (статус ')

В физической базе данных у объекта статуса есть поле employeeID, которого нет в домене - IE: я не храню ссылки на сотрудника из объекта статуса, но физическое поле должно быть выведено у владельца объекта. collection - Фактически, он делает это, если я устанавливаю поле EmployeeID в таблице состояния на nullable - он фактически выполняет 2 оператора SQL - вставку и затем обновление, а EmployeeID устанавливается в обновлении.

Спасибо

Tony

0 голосов
/ 10 февраля 2009

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

0 голосов
/ 09 февраля 2009

Можете ли вы опубликовать код для классов?

Вы пытаетесь сохранить историю статусов сотрудника?

- Правка -
Похоже, вам понадобится «многие ко многим», поскольку у ребенка в отношениях (EmployeeStatus) нет ссылки на родителя (Employee).

- Правка 2 -
Если вы хотите, чтобы вставка выполнялась как 1 вызов БД, вам нужно добавить свойство Employee в класс EmployeeStatus и установить Inverse = true. И я уверен, что вам нужно будет добавить некоторую логику, которая устанавливает двунаправленные отношения в объектах. И.Е.

public void AddStatus(EmployeeStatus status)
{
    this.StatusList.Add(status);
    status.Employee = this;
}
...