How to add an item to a business list

How to add an item to a business list

Old forum URL: forums.lhotka.net/forums/t/12106.aspx


pearljam posted on Friday, August 09, 2013

When I add an item to my list using Add(), I get an exception in BusinessListBase that the item is not a child. How do I make the item I create a child of the list? If I use AddNew everything works, the problem is that I need to pass some things to my business object when I create it so AddNew doesn't work for me.

JonnyBee replied on Friday, August 09, 2013

If I remember correctly the AddNew method returns the new item as type object - so you can cast it to the actual type and set values.

Another option is to call MarkAsChild() method in the new items Contructor or DataPortal_Create or Child_Create -  depending on how the new object is created.

IE: To make an item child you must call the MarkAsChild() method on the object. 

pecen replied on Sunday, August 18, 2013

Hi,

As I understand it, referring to the DataPortal book from the book series "Using CSLA 4" by Rocky, there are 3 common techniques used to add a child object to a list:

1. Calling code creates the new child object, and adds it to the list by calling the collection's Add method.

2. Collection implements an AddItem() method that is responsible for creating the new child object and adding it to the list.

3. Calling code invokes the collection's AddNew() method, and that method creates the new child object and add it to the list (also used by data binding scenarios).

The advantage of technique number 1 and 2 is that you can pass parameter values to the new child object, and it can use those values as part of its initialization. But then you need to write code to support those scenarios.

The BusinessListBase and BusinessBindingListBase classes support technique number 3 by default.

By default, if the AddNew() method is called on an editable list, a new child object will be created and initialized through its Child_Create method, and then it is added to the collection

If you don't need to pass parameter values, but rather just need to initialize the child object, I would personally use the 3rd alternative, override the AddNewCore(), and add a Creator class.

An example of the 3rd alternative (also from the Data Access book) is the following where you do the override in the class that inherits from BusinessListBase:

protected override SkillEdit AddNewCore()
{
  var creator = SkillEditCreator.GetSkillEditCreator();
  var item = creator.Result;
  Add(item);

  return item;
}

Then you add a "Creator" class (likeSkillEditCreator below), and do all your initialization through that class, and the class then returns the initialized child object.

  [Serializable]
  public class SkillEditCreator : ReadOnlyBase<SkillEditCreator>
  {
    public static readonly PropertyInfo<SkillEdit> ResultProperty =
      RegisterProperty<SkillEdit>(c => c.Result);
    public SkillEdit Result
    {
      get { return GetProperty(ResultProperty); }
      private set { LoadProperty(ResultProperty, value); }
    }

    public static SkillEditCreator GetSkillEditCreator()
    {
      return DataPortal.Fetch<SkillEditCreator>();
    }

    private void DataPortal_Fetch()
    {
      Result = DataPortal.CreateChild<SkillEdit>();
    }
  }

Copyright (c) Marimer LLC