开发者

Need some explanations on NHibernate many to one relationships

would you mind help me to better understand what to do with the relationship between my entities and NHibernate?

I have some difficulties to understand what operations I need to do by hand, and what operations NHibernate will do for me (or not).

I have these 2 entities:

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

    public Position()
    {

    }

    public Position(string name, int number)
        : this()
    {
        Name = name;
    开发者_StackOverflow中文版    Number = number;
    }

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

and

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

Here are the fluent mappings:

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

As you can see, one player has one position, but may have no position (so DefaultPosition is nullable).

Here are my questions:

  1. When I associate a position to a player's DefaultPosition, I have to do this through helper methods on Position? (like AddPlayer, DeletePlayer...)

I'd like, when I delete a position, that all the players who have this position, have instead a null DefaultPosition.

  1. Do I have to clear manually the field allPlayers of the position, and manually set null to all associated player's DefaultPosition, or can NHibernate take care of this for me?

  2. Why does NHibernate only does a DELETE FROM Positions WHERE Id... and doesn't update the field DefaultPOsition of the concerned players? I've tried to add a Cascade.Delete on the HasMany in PositionMap, but that doesn't change anything. Do I have to run a custom query which does that?

Thanks in advance


Q1 If you add a property for Players on Position, then you don't need those helper methods.

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
}

then call like:

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

Q2, Q3 you could have a helper method on position to simplify.

something like:

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
}

with a call looking like:

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

Since the players will persist beyond the position but the position gets removed, you wouldn't want to use cascade. Cascade is for deletes, not really updating of id's. For example, delete an order and cascade all of it's line items.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜