I have a simple model where a Player
may choose a unique Selection
of integers which are saved in a Selection
table
Which looks like this
public class Player
{
private readonly ICollection<Selection> selection;
public Player()
{
this.selection = new List<Selection>();
}
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual string EmailAddress { get; set; }
public virtual IEnumerable<Selection> Selection
{
get
{
return this.selection;
}
}
public virtual void UpdateSelection(IEnumerable<int> balls)
{
this.selection.Clear();
this.selection.AddRange(balls.Select(ball => new Selection { Player = this, Number = ball }));
}
}
public class Selection
{
public virtual Player Player { get; set; }
public virtual int Number { get; set; }
}
This is what I'm using to map the selection to the player
this.Bag(
x => x.Selection,
m =>
{
m.Key(k => k.Column("PlayerId"));
m.Access(Accessor.Field);
m.Cascade(Cascade.All);
m.Inverse(true);
},
k => k.OneToMany());
And the selection map has a composed id
this.ComposedId(
x =>
{
x.Property(y => y.Number);
x.ManyToOne(y => y.Player, m => m.ForeignKey("PlayerId"));
});
As I change this list using the UpdateSelection
method of Player
then the Selection
table should insert and delete rows where necessary.
However, if I were to remove a number from the Selection
when the Session.Update method is called I get the following error
Duplicate entry '1-1' for key 'PRIMARY'Could not execute command: INSERT INTO Selection (PlayerId, Number) VALUES (?p0, ?p1)
Which is self explanatory, but fixing it is not. Why is it trying to re-add the numbers, shouldn't it just delete the one I removed?
Update
I change the mapping from a Bag to a Set and now I don't get the duplicate key error. However it does not delete the number I removed from the list.
So in your mapping of the Bag (now Set) you define
m.Cascade(Cascade.All);
m.Inverse(true);
Defining both, Cascade and Inverse(true) would work against each other... Inverse(true) means that the other side should take care of updating changes, wich would negate the Cascade definition...
You should try to set Inverse(false) which would make the Bag responsible for the entity.