I've recently moved across to the latest version of Code Smith (from v5)
I'm using the most recent CSLA templates (from Blake http://code.google.com/p/codesmith/ 3.1.zip)
We're testing some new developments (vb.net/SQL Server 2008) and I have the following object
Currency (Editable Root)
CurrencyList (Editable Root List)
ExchangeRate (Editable Child)
ExchangeRates (Editible Child List)
Each currency has a ExchangeRates child object, detailing the exchange rates for that Currency.
the issue is that when editing the parent Currency object, it is correctly writing the child data to the database however it is not retaining the Exchange Rate ID assigned to it from the database.
I have put a watch on the child object and the child is getting updated with a new ID from the Database and the IsNew is set to False - all OK so far.
However the moment the process returns back to the ExchangeRates list e.g. Next Exchange Rate when inspecting the previous Exchange Rate (that we'd seen saved) the ID is 0 and IsNew = True
The cosequence is that we are now getting duplicate child entries being written when they are clearly being saved (again) each time the Save method is called.
So in a nut-shell ;
1. Parent and Child updates are being saved, so if I reload all the objects and just do updates then it's fine.
2. new Child additions are being saved but the object marked as dirty and IsNew=True even though save is working, so when the user saves again, the child gets re-inserted thus creating duplcates.
Not that this is very helpful, but the last time I was doing this sort of parent/child update was last year (version 5 of Codesmith) and it worked without a problem
Not sure if the recent template changes have mucked something up or if there is a bug in the build of CSLA
Any ideas?
thanks
Andrew
Remember that Save actually returns a new Object, so your code should look like.
bo = bo.Save();
The new object has updated status (IsNew = false) etc.
Hi JonnyBee
you're right in as much as for a ROOT object it'll expect a
bo=bo.save,
which again on the face of it works. However a Child can only seem to be updated through the
For Each child As cExchangeRate In Me
If child.IsDirty Then
child.Insert(cn, parent)
Else
child.Update(cn, parent)
' child = child.Save
End If
Next
the issue is that the CHILD objects are not getting marked as saved (IsDirty=False, IsNew=False) and the ID field is not retained either (the one the Database IS assigning)
If I didn't know better it's almost doing a
1. Dim tempExRate as ExchangeRate = (Child)Exchange Rate.CLONE
2. (Child) Exchange Rate.Save
3.. Return tempExRate - so It returns an object that appears as per the original but without the save flag or values
Any other ideas?
thanks
Andrew
I assume that you are using DataPortal_XYZ for Data Access.
You then have support methods in DataPortal as:
FieldManager.UpdateChildren(parent) - will call Child_Insert/Child_Delete/Child_Update for all child objects in "parent" or
DataPortal.UpdateChild(child) - will call Child_Insert/Child_Delete/Child_Update for all child objects in the "child" list.
These support methods will also call MarkOld to update state automatically.
Semantically the code is like:
BusinessListBase:
protected virtual void Child_Update(params object[] parameters)
{
var oldRLCE = this.RaiseListChangedEvents;
this.RaiseListChangedEvents = false;
try
{
foreach (var child in DeletedList)
DataPortal.UpdateChild(child, parameters);
DeletedList.Clear();
foreach (var child in this)
if (child.IsDirty) DataPortal.UpdateChild(child, parameters);
}
finally
{
this.RaiseListChangedEvents = oldRLCE;
}
}
and in Csla.Server.ChildDataPortal.Update:
.......
if (busObj.IsDeleted)
{
if (!busObj.IsNew)
{
// tell the object to delete itself
lb.CallMethod("Child_DeleteSelf", parameters);
}
if (target != null)
target.MarkNew();
else
lb.CallMethodIfImplemented("MarkNew");
}
else
{
if (busObj.IsNew)
{
// tell the object to insert itself
lb.CallMethod("Child_Insert", parameters);
}
else
{
// tell the object to update itself
lb.CallMethod("Child_Update", parameters);
}
if (target != null)
target.MarkOld();
else
lb.CallMethodIfImplemented("MarkOld");
}
}
else if (obj is CommandBase)
{
// tell the object to update itself
lb.CallMethod("Child_Execute", parameters);
operation = DataPortalOperations.Execute;
}
else
{
// this is an updatable collection or some other
// non-BusinessBase type of object
// tell the object to update itself
lb.CallMethod("Child_Update", parameters);
if (target != null)
target.MarkOld();
else
lb.CallMethodIfImplemented("MarkOld");
}
Unless I am missing something I never have used a explicit layer
perhaps this is a (my) hang-up from previous versions but I have not used anything other than the methods available to the object
e.g. Save - on a Root object and
for each child
If child.isdirty then
if child.isnew then
child.insert(SQLConnection, parent)
else
child.update (SQLCOnnection, parent)
endif
next
As I said before this has always worked in the past. so something has changed as the child objects are no longer getting updated as saved/clean
Any other ideas, or do I need to scrap it and find a previous version of Codesmith and associated templates as this is the only thing I've changes, as well as the version of the CSLA dll of course
thanks
A
I came accross the same probleem:
var queue = MyQueue.NewMyQueue();
queue.Aanmaakdatum =
SmartDate.Now;
queue.ClientNumber =
"123456789";
var item = queue.AddNewMyQueueItem();
queue = queue.Save();
I see now that child object item is new and that the id has not been set. Ay suggestions? This probleem doesn't occure in CSLA version 2.1.
Copyright (c) Marimer LLC