Given that your CategoryParent is just a joining type, have you considered implementing this using ManyToMany like this:
public class Category
{
public virtual IList<Category> Parents { get; set; }
public virtual IList<Category> Children { get; set; }
}
public class CategoryMap : ClassMap<Category>
{
HasManyToMany(x => x.Parents)
.ParentKeyColumn("ChildID")
.ChildKeyColumn("ParentID")
.Inverse();
HasManyToMany(x => x.Children)
.ParentKeyColumn("ParentID")
.ChildKeyColumn("ChildID");
}
Unless I'm missing something, this will simplify things considerably, and
may resolve your issues.
On Thu, Jan 14, 2010 at 7:50 PM, Ton <[email protected]> wrote:
> Hi there. We are trying to implement a solution in fnh where we will
> handle Category Hierarchy. We will use a "Category" table for all the
> categories and another "CategoryParents" table where we will store
> parent-child mapping info - basically sufficed by a "ParentId" field
> and a "ChildId" field.
>
> We aim to be able to get all of a Category's parents and children
> integrated into the mapping and so we have a list of CategroyParents
> in our Category and a simple implementation of wrapping individual
> Parent / Child lists :
>
>
> public class Category : Entity
> {
> public virtual IList<CategoryParent> ParentsAndChildren { get;
> protected set; }
>
> public virtual IList<Category> Parents
> {
> get
> {
> return ParentsAndChildren.Where(c => c.Child ==
> this).Select(c => c.Parent).ToList();
> }
> }
>
> public virtual IList<Category> Children
> {
> get
> {
> return ParentsAndChildren.Where(c => c.Parent ==
> this).Select(c => c.Child).ToList();
> }
> }
>
> public Category()
> {
> ParentsAndChildren = new List<CategoryParent>();
> }
> }
>
>
> public class CategoryParent : Entity
> {
> public virtual Category Parent { get; protected set; }
> public virtual Category Child { get; protected set; }
>
> protected CategoryParent() { }
> public CategoryParent(Category parent, Category child)
> {
> Parent = parent;
> Child = child;
> }
> }
>
>
> For the fnh mapping:
>
>
> public class CategoryMap : ClassMap<Category>
> {
> public CategoryMap()
> {
> Id(p => p.Id).GeneratedBy.Identity();
>
> HasMany(p => p.ParentsAndChildren)
> .KeyColumn("ParentId")
> .Cascade.All()
> .Cascade.AllDeleteOrphan()
> .Inverse()
> .Fetch.Select()
> .LazyLoad();
>
> //HasMany(p => p.ParentsAndChildren)
> //.KeyColumn("ChildId")
> //.Cascade.All()
> //.Cascade.AllDeleteOrphan()
> //.Inverse()
> //.Fetch.Select()
> //.LazyLoad();
> }
> }
>
>
> public class CategoryParentMap : ClassMap<CategoryParent>
> {
> public CategoryParentMap()
> {
> Id(p => p.Id).GeneratedBy.Identity();
> References(p => p.Parent).Column("ParentId");
> References(p => p.Child).Column("ChildId");
> }
> }
>
>
> We are using schemaExport and so far, the DB schema that gets
> generated is ok. For our tests, the Category table gets filled with 3
> Categories; and the CategoryParents table is populated with 2 rows,
> mapping Category 1 as parent for Categories 2 & 3.
>
> However, we encounter issue/s whenever we try to check for a
> Category's parent or child such as follows:
>
> Assert.True(tempCategory2.Parents.Contains(tempCategory1));
> Assert.AreEqual(2, tempCategory1.Children.Count);
>
> With the categorymapping above, the first assertion fails and
> generates the following SQL:
>
> SELECT parentsand0_.ParentId as ParentId1_,
> parentsand0_.CategoryParentId as Category1_1_,
> parentsand0_.CategoryParentId as Category1_8_0_, parentsand0_.ParentId
> as ParentId8_0_, parentsand0_.ChildId as ChildId8_0_ FROM
> CategoryParents parentsand0_ WHERE parentsand0_.parent...@p0;@p0 = 2
>
> while the second assertion succeeds and generates the SQL:
>
> SELECT parentsand0_.ParentId as ParentId1_,
> parentsand0_.CategoryParentId as Category1_1_,
> parentsand0_.CategoryParentId as Category1_8_0_, parentsand0_.ParentId
> as ParentId8_0_, parentsand0_.ChildId as ChildId8_0_ FROM
> CategoryParents parentsand0_ WHERE parentsand0_.parent...@p0;@p0 = 1
>
> When we edit the categorymapping to interchange the commented code
> lines, the first assertion succeeds with the following SQL:
>
> SELECT parentsand0_.ChildId as ChildId1_,
> parentsand0_.CategoryParentId as Category1_1_,
> parentsand0_.CategoryParentId as Category1_8_0_, parentsand0_.ParentId
> as ParentId8_0_, parentsand0_.ChildId as ChildId8_0_ FROM
> CategoryParents parentsand0_ WHERE parentsand0_.child...@p0;@p0 = 2
>
> while the second assertion fails with the following SQL:
>
> SELECT parentsand0_.ChildId as ChildId1_,
> parentsand0_.CategoryParentId as Category1_1_,
> parentsand0_.CategoryParentId as Category1_8_0_, parentsand0_.ParentId
> as ParentId8_0_, parentsand0_.ChildId as ChildId8_0_ FROM
> CategoryParents parentsand0_ WHERE parentsand0_.child...@p0;@p0 = 1
>
> We thought that the fnh mapping would "automatically" handle setting
> which field to choose as filter when trying to load the Parents and
> Children but from the generated SQL, it seems that the filtering is
> based on the keycolumn only. We already tried a few other approaches
> to handle how the filters will be defined (also researched if there is
> a way to have an "OR" in the filter) but can't seem to find suitable
> solutions. We hope you can review our code and advise for any solution
> that we can apply for our purposes.
>
> Thanks and more power.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Fluent NHibernate" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<fluent-nhibernate%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/fluent-nhibernate?hl=en.
>
>
>
>
-- You received this message because you are subscribed to the Google Groups "Fluent NHibernate" 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/fluent-nhibernate?hl=en.
