Hello,
I have the following entity, Board, which represents Othello
positions:
public class Board : Entity // Entity defines Id as Guid
{
private ISet<Board> successors = new HashSet<Board>();
private ISet<Board> parents = new HashSet<Board>();
public virtual long Empty { get; private set; }
public virtual long Mover { get; private set; }
public virtual IEnumerable<Board> Parents { get { return
parents; } }
public virtual void AddParent(Board parent)
{
parents.Add(parent);
}
public virtual IEnumerable<Board> Successors { get { return
successors; } }
public virtual void AddSuccessor(Board successor)
{
successors.Add(successor);
}
public virtual IEnumerable<Board> CalculateSuccessors()
{ ... }
}
The intent is to store the positions along with their successors
(children) and predecessors (parents). The mapping I came up with
looks like this:
public class BoardMap : ClassMap<Board>
{
public BoardMap()
{
Id(x => x.Id);
NaturalId().Property(x => x.Empty).Property(x =>
x.Mover);
HasManyToMany(x => x.Successors)
.Access.ReadOnlyPropertyThroughLowerCaseField()
.ParentKeyColumn("ParentId")
.ChildKeyColumn("ChildId")
.Cascade.SaveUpdate() // ?
.AsSet(SortType.Unsorted)
.Table("Successors");
HasManyToMany(x => x.Parents)
.Access.ReadOnlyPropertyThroughLowerCaseField()
.ParentKeyColumn("ParentId")
.ChildKeyColumn("ChildId")
.Cascade.SaveUpdate() // ?
.AsSet(SortType.Unsorted)
.Table("Parents");
}
Here's how I want to add a position. If the position already exists,
just skip it, otherwise set up the association between parent/
successor:
// all of the following is running inside an ISession, wrapped with
transaction
var parent = new Board(...);
if (Find(parent) == null)
{
log.InfoFormat("Adding {0}: {1}", currentPosition++, parent);
foreach (var s in parent.CalculateSuccessors())
{
// get from store, if it exists
var successor = Find(s) ?? s;
successor.AddParent(parent);
parent.AddSuccessor(successor);
}
session.Save(parent);
}
else
{
log.InfoFormat("Existing {0}: {1}", currentPosition++, parent);
}
Find simply looks like this:
public Board Find(Board item)
{
// Transact will run inside the current transaction, or start
new if
there is none
return Transact(() => from b in session.Query<Board>()
where b.Empty ==
item.Empty && b.Mover == item.Mover
select
b).SingleOrDefault();
}
The problem I am seeing is that it seems cascading is doing too much.
I believe I've wrongly configured NHibernate to cascade to children's
children's children, etc. Even adding 91 positions takes too long.
Here's what I am seeing in the log output:
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|processing
cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction
for: GridBook.Domain.Board
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Parents
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Parents
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done
processing cascade NHibernate.Engine.CascadingAction
+SaveUpdateCascadingAction for: GridBook.Domain.Board
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|processing
cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction
for: GridBook.Domain.Board
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors
etc, several thousand lines for only 91 positions. What am I doing
wrong here? This could be considered batch-import and I will be
importing millions of positions.
Any advice would be greatly appreciated!
Thanks in advance!
Regards,
Daniel Lidström
Stockholm, Sweden
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.