Нужны некоторые пояснения по NHibernate много к одному отношения - PullRequest
2 голосов
/ 29 июня 2010

Не могли бы вы помочь мне лучше понять, что делать с отношениями между моими сущностями и NHibernate?

У меня есть некоторые трудности, чтобы понять, какие операции мне нужно делать вручную, и какие операции NHibernate будет делать для меня (или нет).

У меня есть 2 сущности:

public class Position : BaseEntity<int, Position>
{
    private IList<Player> allPlayers = new List<Player>();

    public Position()
    {

    }

    public Position(string name, int number)
        : this()
    {
        Name = name;
        Number = number;
    }

    public string Name { get; set; }
    public int Number { get; set; }
}

и

public class Player : BaseEntity<int, Player>
{
    public Player()
    {
        Visible = true;
    }

    public Player(string firstName, string lastName, int defaultNumber, Sex sex = Sex.Male, Position defaultPosition = null)
        : this()
    {
        FirstName = firstName;
        LastName = lastName;
        DefaultNumber = defaultNumber;
        Sex = sex;
        DefaultPosition = defaultPosition;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Position DefaultPosition { get; set; }
}

Вот беглые отображения:

public class PositionMap : ClassMap<Position>
{
    public PositionMap()
    {
        Id(pp => pp.Id)
            .GeneratedBy.Increment();

        Map(pp => pp.Name)
            .Not.Nullable();

        Map(pp => pp.Number)
            .Not.Nullable();

        HasMany<Player>(Reveal.Member<Position>("allPlayers"))
            .Access.CamelCaseField();
    }
}

public class PlayerMap : ClassMap<Player>
{
    public PlayerMap()
    {
        Table("Players");

        Id(p => p.Id)
            .GeneratedBy.Increment();

        Map(p => p.FirstName)
            .Not.Nullable()
            .UniqueKey("Players_Unique_FirstName_LastName");

        Map(p => p.LastName)
            .Not.Nullable()
            .UniqueKey("Players_Unique_FirstName_LastName");

        References(p => p.DefaultPosition);
    }
}

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

Вот мои вопросы:

  1. Когда я связываю позицию с DefaultPosition игрока, я должен сделать это с помощью вспомогательных методов на Position? (например, AddPlayer, DeletePlayer ...)

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

  1. Должен ли я вручную очистить поле allPlayers от позиции и вручную установить значение null в DefaultPosition всех связанных игроков, или NHibernate позаботится об этом для меня?

  2. Почему NHibernate только УДАЛЯЕТ из позиций ГДЕ Id ... и не обновляет поле DefaultPOsition соответствующих игроков? Я пытался добавить Cascade.Delete на HasMany в PositionMap, но это ничего не меняет. Должен ли я выполнить пользовательский запрос, который делает это?

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

1 Ответ

2 голосов
/ 29 июня 2010

Q1 Если вы добавите свойство для Player on Position, вам не понадобятся эти вспомогательные методы.

public class Position : BaseEntity<int, Position>
{
    private IList<Player> allPlayers = new List<Player>();

    //read only
    public IList<Player> Players { get { return allPlayers;} }

    //... rest of class omitted
}

, а затем вызовите как:

var position = new Position();
position.Players.Add(new Player());

Q2, Q3 выможет иметь вспомогательный метод для упрощения позиции.

что-то вроде:

public class Position : BaseEntity<int, Position>
{
    public void RemoveAll()
    {
       // null out the position on players
       foreach(var player in allPlayers)
       {
           player.Position = null; // SETS PositionId FIELD IN PLAYER TABLE TO NULL
       }
       allPlayers.Clear();
    }

    // ... rest of class omitted
}

с вызовом, похожим на:

using(var session = SessionFactory.GetCurrentSession())
{
   using(var tx = session.BeginTransaction())
   {
      position.RemoveAll();
      position.Delete();
      tx.Commit();
   }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...