代码之家  ›  专栏  ›  技术社区  ›  Emidee

需要一些关于NHibernate多对一关系的解释吗

  •  2
  • Emidee  · 技术社区  · 16 年前

    你能帮我更好地理解我的实体和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; }
    }
    

    以下是fluent映射:

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

    以下是我的问题:

    1. 当我将一个位置关联到一个玩家的DefaultPosition时,我必须通过position上的helper方法来实现这一点(比如AddPlayer,DeletePlayer…)

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

    2. 为什么NHibernate只做 从Id所在的位置删除。。。 不更新相关球员的场地位置吗?我试着在PositionMap中添加一个Cascade.Delete,但这并没有改变任何事情。我必须运行一个自定义查询吗?

    1 回复  |  直到 16 年前
        1
  •  2
  •   Tim Hoolihan    16 年前

    如果你为玩家添加了一个属性,那么你就不需要那些助手方法了。

    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你可以在位置上有一个helper方法来简化。

    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。Cascade用于删除,而不是更新id。例如,删除订单并层叠其所有行项目。

    推荐文章