views:

440

answers:

1

What I have is this:

  • Domain.List has many ListToListMemberships called "SubLists"
  • Domain.List also has many ListToListMemberships called "ParentLists"
  • ListToListMembership has one List (the parent).
  • ListToListMembership has another List (the member).

Given this I want the following test to pass:

    [Test]
    public void WhenDeletingChildMembershipShouldBeDeletedButNotParent()
    {
        var list = new Domain.List();
        var child = new Domain.List();

        var membership = new ListToListMembership()
        {
            Member = child,
        };

        list.SubLists.Add(membership);
        Session.Save(list);
        Session.Flush();
        Session.Evict(list);
        Session.Evict(child);

        var childFromDb = Session.Linq<Domain.List>()
            .FirstOrDefault(l => l.ID == child.ID);

        Assert.IsNotNull(childFromDb, "child wasn't saved when the parent was saved");
        Assert.AreNotSame(child, childFromDb, "child was pulled from cache not the db");

        //This will allow it to pass, but I don't want to have to do this.
        //  foreach (var m in childFromDb.ParentLists)
        //  {
        //      m.List.SubLists.Remove(m);
        //      Session.Save(m.List);
        //  }

        Session.Delete(childFromDb);
        Session.Flush();
        Session.Evict(childFromDb);

        var membershipFromDb = Session.Linq<ListToListMembership>()
            .FirstOrDefault(m => m.ID == membership.ID);

        Assert.IsNull(membershipFromDb, "membership wasn't deleted");

        var parentFromDb = Session.Linq<Domain.List>()
            .FirstOrDefault(l => l.ID == list.ID);

        Assert.IsNotNull(parentFromDb, "parent list was deleted");
    }

Basically when I create a list and add a list membership with a member to it, I want the membership and the member to be created automatically.

Also when I delete either the parent list or the member list, I would like the membership deleted but not the member list (in the case of the parent being deleted) nor the parent list (in the case of the member list being deleted).

Domain.List:

    <!-- Other relevant fields -->

    [HasMany(typeof(ListToListMembership),ColumnKey="ListId",
        Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
    public IList<ListToListMembership> SubLists{
        get;
        set;
    }
    [HasMany(typeof(ListToListMembership),ColumnKey="MemberId",
        Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
    public IList<ListToListMembership> ParentLists {
        get;
        set;
    }

ListToListMembership:

    <!-- other relevant fields -->
    [BelongsTo("ListId",Cascade=CascadeEnum.SaveUpdate)]
    public List List {
        get;
        set;
    }
    [BelongsTo("MemberId", Cascade = CascadeEnum.SaveUpdate)]
    public List Member {
        get;
        set;
    }
A: 

This case is rather complex and I can't follow all of it.

What happens is probably caused by cascades. I don't know how you mapped the classes.

I'm not sure why you need this ListToListMembership class. You probably can get rid of it by simplifying the domain model. There will still be a connection table in the database, but this is managed by NH.

Then I think that you try to put too many logic into the cascade-configuration. Sometimes cascading is actually business logic. If the lifecycle of an object is strictly coupled to another "parent" object, it is a case for cascades. In any more complex case, it should be implemented as part of the business logic. (Because the objects will have their own life cycle which needs to be managed by the business logic)

Stefan Steinegger
Thank you.The reason I have the membership class is because a Domain.List will have specific property values depending on the Domain.List it is a member of when it is being displayed. The issue is definitely a cascading one and the reason is that if either the parent or the child gets deleted, I know longer need their Memberships.
Gabe Anzelini