I want to put a tree structure (stored as an adjacency list) into a database, and I want to use Fluent NHibernate with Convention mapping to do it. I have the following code:
[...]
NamespaceAutomapping automapping = new NamespaceAutomapping("NHibernateTree.Model", false); //Maps the classes in the namespace NHibernateTree.Model, false meaning to not map sub-namespaces like NHibernateTree.Model.ABC
FluentConfiguration fluentConfiguration = Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.PostgreSQLConfiguration.PostgreSQL82.ConnectionString(connectionString))
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<TreeNode>(automapping)
//.Conventions.Add<ForeignKeyNameConvention>()
));
[...]
ISessionFactory SessionFactory = fluentConfiguration.BuildSessionFactory();
using (ISession session = SessionFactory.OpenSession())
{
TreeNode root = new TreeNode() { Value = "Root" };
TreeNode childA = new TreeNode() { Parent = root, Value = "Child A" };
root.Children.Add(childA);
TreeNode childB = new TreeNode() { Parent = root, Value = "Child B" };
root.Children.Add(childB);
session.Save(root);
session.Save(childA);
session.Save(childB);
}
using (ISession session = SessionFactory.OpenSession())
{
TreeNode root = session.Query<TreeNode>().First(tn => tn.Value == "Root");
Console.WriteLine(root.ToString());
}
The convention that is out-commented looks like this:
public class ForeignKeyNameConvention : ForeignKeyConvention
{
protected override String GetKeyName(Member property, Type type)
{
return String.Format("\"{0}Id\"", null == property ? type.Name : property.Name);
}
}
And the class NHibernateTree.Model.TreeNode looks like this: (This is the only class in that namespace)
class TreeNode
{
public virtual int Id { get; set; }
public virtual TreeNode Parent { get; set; }
public virtual ICollection<TreeNode> Children { get; set; }
public virtual String Value { get; set; }
public TreeNode()
{
Children = new Collection<TreeNode>();
}
public override string ToString()
{
[...]
}
}
Now, if I run this code, the output is:
Root
Child A
Child B
And the table in the database looks like this:
Column | Type
-----------+-----------------------
id | integer
value | character varying(255)
parent_id | integer
id | value | parent_id
----+---------+-----------
1 | Root |
2 | Child A | 1
3 | Child B | 1
So far, so good. But if I un-comment the line in the program that adds the convention, then strange things happen. The output of the program is only "Root" (i.e. NHibernate does not find the reference to the children anymore), and the table looks like this instead:
Column | Type
------------+-----------------------
id | integer
value | character varying(255)
ParentId | integer
TreeNodeId | integer
id | value | ParentId | TreeNodeId
----+---------+----------+------------
1 | Root | |
2 | Child A | 1 |
3 | Child B | 1 |
The column "TreeNodeId" is NULL in all rows.
Obviously the convention is messing something up. I would want to use this convention to get the names of foreign keys nice, but I can't get it to work.
I have found some posts on SO where people solve basically the same problem, but not with conventions.
Any help appreciated!