2

你介意帮助我更好地理解如何处理我的实体和 NHibernate 之间的关系吗?

我很难理解我需要手动执行哪些操作,以及 NHibernate 将为我执行哪些操作(或不执行)。

我有这两个实体:

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...)

我希望,当我删除一个位置时,所有拥有该位置的玩家都有一个空的 DefaultPosition。

  1. 我是否必须手动清除该位置的 allPlayers 字段,并将所有关联玩家的 DefaultPosition 手动设置为 null,或者 NHibernate 可以为我处理这个问题吗?

  2. 为什么 NHibernate 只执行DELETE FROM Positions WHERE Id...而不会更新相关玩家的字段 DefaultPOsition?我试图在 PositionMap 的 HasMany 上添加 Cascade.Delete,但这并没有改变任何东西。我是否必须运行一个自定义查询来做到这一点?

提前致谢

4

1 回答 1

2

Q1 如果您为位置上的玩家添加一个属性,那么您不需要那些辅助方法。

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();
   }
}

由于玩家将持续超出该位置但该位置被移除,因此您不想使用级联。Cascade 用于删除,而不是真正更新 id。例如,删除一个订单并将其所有订单项级联。

于 2010-06-29T17:51:51.813 回答