Hello,
I'm running into a little difficulty with a collection. The collection is intended to be an Editable Root Collection as described on p. 187 in the current book.
The collection is defined like this:
public class ClientList : BusinessListBase<ClientList, Client>
The child client object is defined as
public
class Client : BusinessBase<Client>If I understand p.189 correctly, the BLB's default implementation of DataPortal_Update should call the Child_Update on the children. I have no update methods in the list class as shown in the example on p. 188. However when the Silverlight CslaDataProvider Save method is invoked, the base class throws at line 113 in BusinessBase (version 3.6.2)
public virtual T Save(){I'm trying to use this as follows:
I have a silverlight form that's a "client editor". The bottom half has a grid control of clients bound to the list provided by the data provider. When the selection changes, the selected item is made the data context of the edit form in the top half of the control.
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e){HorizonSoftware.OSMobileStock.BusinessObjects.Client client = e.AddedItems[0] as HorizonSoftware.OSMobileStock.BusinessObjects.Client;Thanks for taking a look.
Elton
I
think you have an issue on your form. I think you are calling Save() on
an individual client record instead of ClientList object. If you can
paste the code that fires Save on your form, I can tell for sure.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: esaulsberry
[mailto:cslanet@lhotka.net]
Sent: Thursday, June 04, 2009 5:34 PM
To: Sergey Barskiy
Subject: [CSLA .NET] Editable Root Collection
Hello,
I'm running into a little
difficulty with a collection. The collection is intended to be an Editable Root
Collection as described on p. 187 in the current book.
The
collection is defined like this:
public class ClientList :
BusinessListBase<ClientList,
Client>
The child
client object is defined as
public class Client : BusinessBase<Client>
...
internal static
Client GetClient(Data.Client client){
return DataPortal.FetchChild<Client>(client);
}
...
private void
Child_Update() { ...
If I
understand p.189 correctly, the BLB's default implementation of
DataPortal_Update should call the Child_Update on the children. I have no
update methods in the list class as shown in the example on p. 188.
However when the Silverlight CslaDataProvider Save method is invoked, the base
class throws at line 113 in BusinessBase (version 3.6.2)
public virtual T Save(){
T result;
if (this.IsChild)
throw new NotSupportedException(Resources.NoSaveChildException);
I'm trying
to use this as follows:
I have a
silverlight form that's a "client editor". The bottom half has
a grid control of clients bound to the list provided by the data
provider. When the selection changes, the selected item is made the data
context of the edit form in the top half of the control.
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs
e){HorizonSoftware.OSMobileStock.BusinessObjects.Client
client = e.AddedItems[0] as
HorizonSoftware.OSMobileStock.BusinessObjects.Client;
if (client != null){
GrdClientForm.DataContext = client;
}
}
The save
button is tied to the save function on the data provider. This seems like
a reasonable approach. I don't what to have to round trip every time the
selection changes to fetch an editable root for the edit form. The book
seems to indicate this pattern is supported but if it is I haven't found the
magic sprinkles.
Thanks for
taking a look.
Elton
Looks like Rocky had the key.
For what it's worth, here's how it's hooked up.
<csla:CslaDataProvider x:Key="CslaDpClient"Btw, in 3.6.2 and higher you can use a shorter ObjectType value:
ObjectType=”HorizonSoftware.OSMobileStock.BusinessObjects.ClientList,
HorizonSoftware.OSMobileStock.BusinessObjects”
The version/culture/etc aren’t required unless you sign
the assembly.
Rocky
I know there's some minor errata in that area of the book - like one word is wrong - but that could be the issue.
For a root collection you do need to implement DataPortal_Update(), because CSLA doesn't know how to open your database connection, object context, data context or whatever you are using to talk to your database.
Also, CSLA doesn't know what transactional model you want, so you need to implement the DataPortal_Update() method so you can put the appropriate Transactional attribute on the method.
But the implementation is generally easy, because Child_Update() does all the work:
protected override void DataPortal_Update()
{
// open database connection or whatever
base.Child_Update();
// close database connection or whatever
}
Change your code to this instead...(root objects do not call "Child" methods)
internal static Client GetClient(int clientID){
return DataPortal.Fetch<Client>(clientID);
}
...
private void DataPortal_Fetch() { ...
private void DataPortal_Update() { ...
private void DataPortal_Insert() { ...
private void DataPortal_Delete() { ...
cdkisa:Change your code to this instead...(root objects do not call "Child" methods)
Thanks for taking a look. In this case, the collection is the root and the business object is a child of the collection, so the UI calls for the collection and it does the rest. The individual BO's aren't created by the UI individually.
Elton
Copyright (c) Marimer LLC