Deleting ContentItems from Memory

Topics: Developer Forum, Project Management Forum, User Forum
Feb 24, 2009 at 10:28 PM
I have a situation where I am adding a ContentItem to a page in memory. I have no intention of saving this ContentItem to the database. The ContentItem is created and displayed during runtime. I am running into a problem because on the same page that I am adding this ContentItem I would like to save another ContentItem to the database. When I try to save this specific ContentItem to the database, both items are saved. I am not sure why this is happening.

Here is some psuedocode:

PageLoad(){
  ContentItemDontSave item1 = new ContentItemDontSave();
  item1.Properties = properties;
  item1.Name = "item1";
  item1.ZoneName = "Top";
  item1.AddTo(CurrentPage);
}

ButtonClick(){
  ContentItemToSave item2 = new ContentItemToSave();
  item2.Properties = properties;
  item2.Name = "item2";
  item2.ZoneName = "Bottom";
  item2.AddTo(CurrentPage);
  N2.Context.Persister.Save(item2);
}

When I do the save in the button click, both item1 and item2 are saved to the database. I am not sure why this is the case, and if this should be the case.

As a temporary work around I would like to remove item1 from memory before saving, but I cannot figure out how to do this. I have tried this:

            IList< ContentItemDontSave> items = CurrentPage.GetChildren< ContentItemDontSave>();
            if (items.Count > 0)
                for (int i = items.Count - 1; i >= 0; i--)
                    CurrentPage.GetChildren< ContentItemDontSave >().RemoveAt(i);

But this doesn't remove the items from the page.

Some help would be appreciated.

Thanks
Daniel
Feb 25, 2009 at 8:10 AM
"class ContentItemDontSave : N2.Persistence.IActiveContent ... " ?
Feb 25, 2009 at 3:18 PM
Here is my implementation of the IActiveContent Interface in the ContentItemDontSave class. Even After this implementation the ContentItemDontSave is being saved to the database. It doesn't appear my implementation of the Save method is being called because the Exception I am throwing in the Save function is never thrown.

    #region IActiveContent Members

    public N2.ContentItem CopyTo(N2.ContentItem destination)
    {
        N2.ContentItem cloned = this.Clone(true);
        cloned.Parent = destination;
        return cloned;
    }

    public void Delete()
    {
        //Since this item isn't saved to the database, it doesn't need to be deleted
    }

    public void MoveTo(N2.ContentItem destination)
    {
        // Since this item is not persisted in any way, the MoveTo can just use the CopyTo.
        this.CopyTo(destination);        
    }

    public void Save()
    {
        throw new System.Exception("The ContentItemDontSave.Save() function was called.");
        //This item will not be saved to the database. It will not be persisted.
    }

    #endregion

What am I missing?

Thanks
Daniel
Coordinator
Feb 25, 2009 at 4:32 PM
The item is beeing saved by a nhibernate cascade. To avoid saving it to the database you shouldn't add it to Children. Alternatives includes overriding GetChildren and returning a customized list.
Feb 25, 2009 at 6:17 PM
First, is there a way to display the ContentItemDontSave item1 on the CurrentPage without using the AddTo function?

Second, after trying the solution of implementing IActiveContent on ContentItemDontSave I am confused as to why this doesn't work. It appears that in the ContentPersister object in the the N2.Persistence.NH Namespace you account for the IActiveContent instances in the Save function by checking if the ContentItem to save is an insance of the IActiveContent Interface. I am not sure why this code isn't working?

Once again thanks for your help.
Daniel
Coordinator
Feb 25, 2009 at 7:42 PM
The IActiveContent is specialized to handle the situation where content items are dynamically generated. For example folders and files administered through the regular interface. They are not stored in a database. Take a look at the tests and see if the situation fits yours. The interface is only invoked when the item is saved directly, not when it's saved by a cascade (which happens when it's added to a parent using AddTo).

If you just want to set CurrentPage you can do that. The question is if you want the page to respond to an url and be edited by an administrator.
Feb 25, 2009 at 9:46 PM
What exactly do you mean "just set the CurrentPage"? The  ContentItemDontSave item1 doesn't have a CurrentPage property and inherits from ContentItem.

Thanks
Daniel
Coordinator
Feb 27, 2009 at 10:10 PM
I mean you can assign the property on in OnInit of the aspx page codebehind:

override OnInit:
    CurrentPage = new ContentItemDontSave()

What I don't understand is the reason for adding the ContentItemDontSave to CurrentPage. If you want it to appear in the menu it's possible to achieve this in other ways, e.g. overriding GetChildren on the ContentItemToSave and returning an additional item.