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!
Read chapters 17 and 18, that should help a lot.
Hello,
private static readonly PropertyInfo< ItemList > _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);
internal static ItemList GetByProductId(System.String productId)This calls Child_Fetch on the list object and looks something like this:
{
var criteria = new ItemCriteria{ProductId = productId};
return DataPortal.FetchChild< ItemList >(criteria);
}
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