How to add a list child and how to populate it

How to add a list child and how to populate it

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


brafales posted on Friday, November 05, 2010

Hi,

I'm new to CSLA and working now on a project in which I need to add an EditableChildList to a root object. I've been reding the book on CSLA and I have two questions:

1) How do I add this Child List in the root class, just as any other property?

2) In the book it's stated that the root object usually has to provide the childdata so the child is fetched using that data in the childlist class:

 

internal static EditableChildList GetEditableChildList(

      object childData)

    {

      return DataPortal.FetchChild<EditableChildList>(childData);

    }

The question is: how do I get this child data in the root object and where exactly I have to call this method so when I fetch a root object, it automatically fetches all it's children data?

Thanks!

RockfordLhotka replied on Friday, November 05, 2010

Read chapters 17 and 18, that should help a lot.

bniemyjski replied on Friday, November 05, 2010

Hello,

  1. Yes, but it is slightly different. The below code is a EditableChildList (ECL) property that is lazy loaded. You would add it like this:
  2.         private static readonly PropertyInfoItemList > _itemsProperty = RegisterProperty<ItemList>(p => p.Items, Csla.RelationshipTypes.Child);
            public ItemList Items
            {
                get
                {
                    bool cancel = false;
                    OnChildLoading(_itemsProperty, ref cancel);
        
                    if (!cancel)
                    {
                        if(!FieldManager.FieldExists(_itemsProperty))
                        {
    #if SILVERLIGHT
                            //MarkBusy();
                            var criteria = new PetShop.Business.ItemCriteria {ProductId = ProductId};
                            

                            if((true))
                            {
                                PetShop.Business.ItemList.Exists(criteria,(o,e) =>
                                {
                                    if (e.Error != null)
                                        throw e.Error;

                                    if(!e.Object.Result)
                                    PetShop.Business.ItemList.NewListAsync((o1, e1) =>
                                    {
                                        if (e1.Error != null)
                                            throw e1.Error; 

                                        this.LoadProperty(_itemsProperty, e1.Object);

                                        //MarkIdle();
                                        OnPropertyChanged(_itemsProperty);
                                    });
                                    else
                                    PetShop.Business.ItemList.GetByProductIdAsync(ProductId, (o2, e2) =>
                                    {
                                        if (e2.Error != null)
                                            throw e2.Error; 

                                        this.LoadProperty(_itemsProperty, e2.Object.Child);

                                        //MarkIdle();
                                        OnPropertyChanged(_itemsProperty);
                                    });
                                });
                            }
    #else
                            var criteria = new PetShop.Business.ItemCriteria {ProductId = ProductId};
                            
        
                            if(!PetShop.Business.ItemList.Exists(criteria))
                                LoadProperty(_itemsProperty, PetShop.Business.ItemList.NewList());
                            else
                                LoadProperty(_itemsProperty, PetShop.Business.ItemList.GetByProductId(ProductId));
    #endif
                        }
                    }

                    return GetProperty(_itemsProperty);
                }
            }
    Then, in your DataPortal_Insert and DataPortal_Update in the Root object where you are adding this property to
    you would need to make a call to the feild manager and tell it to update the children like this: 
    FieldManager.UpdateChildren(this, connection);
  3. Yes, this is a factory method and it is placed in the EditableChildList class.
            internal static ItemList GetByProductId(System.String productId)
            {
                var criteria = new ItemCriteria{ProductId = productId};
                
                return DataPortal.FetchChild< ItemList >(criteria);
            }
    This calls Child_Fetch on the list object and looks something like this:
            private void Child_Fetch(ItemCriteria criteria)
            {
                bool cancel = false;
                OnFetching(criteria, ref cancel);
                if (cancel) return;

                RaiseListChangedEvents = false;

                // Fetch Child objects.
                string commandText = string.Format("SELECT [ItemId], [ProductId], [ListPrice], [UnitCost], [Supplier], [Status], [Name], [Image] FROM [dbo].[Item] {0}"ADOHelper.BuildWhereStatement(criteria.StateBag));
                using (SqlConnection connection = new SqlConnection(ADOHelper.ConnectionString))
                {
                    connection.Open();
                    using (SqlCommand command = new SqlCommand(commandText, connection))
                    {
                        command.Parameters.AddRange(ADOHelper.SqlParameters(criteria.StateBag));

                        using(var reader = new SafeDataReader(command.ExecuteReader()))
                        {
                            if(reader.Read())
                            {
                                do
                                {
                                    this.Add(new PetShop.Business.Item(reader));
                                } while(reader.Read());
                            }
                        }
                    }
                }

                RaiseListChangedEvents = true;

                OnFetched();
            }

The this.Add(object) method creates a new EditableChild based on the returned DataReader.

We have a fully working PetShop Sample application that can be found here. Also if you wish to haveall of this code generated for you against your own database schema (what is familair to you) please check out the CodeSmith CSLA Templates that I wrote.

 Please let me know if you have any questions.

Copyright (c) Marimer LLC