Client DataPortal.Update loses data

Client DataPortal.Update loses data

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


ByeByeDelRay posted on Tuesday, November 24, 2009

I'm sure I'm missing something very simple, but when I run this code

Protected Overrides Sub DataPortal_Insert()
Dim params As SqlParameters = GetUpsertParams()
SqlHelper.ExecuteNonQuery(Config.ConnectionStrings.LaborAllocationConnectionString, CommandType.StoredProcedure, "ALLOCATION_INSERT", params.ToArray)
Me._id = CInt(params("@Id").Value)
End Sub

my data is saved and the id is returned -- BUT

when the returned object gets to the following Client.DataPortal method:

Public Function Update(Of T)(ByVal obj As T) As T

Return DirectCast(Update(CObj(obj)), T)

End Function

the id value disappears.

I am using CSLA 3.5. I've read the note at the top of the DataPortal method that says "
''' If the server-side DataPortal is running remotely, this will be a new and
''' different object from the original, and all object references MUST be updated
''' to use this new object.
", but I am unsure if this is the case for me or what technique I would use to reload an object whose Id is missing.

Also, one think I've noticed is that although I am using TransactionScope, the DataPortal says I am using Manual. Could this have something to do with it?

I'm relatively new to CSLA's DataPortal, so any explanations, long or short, will be greatly appreciated.

Thanks!

RockfordLhotka replied on Tuesday, November 24, 2009

You need to use the result of the Save() call in your client code:

obj = obj.Save()

The data portal returns a new object as a result of Save(), and it is that new object that has the updated values (like your new id value) from the save operation.

ByeByeDelRay replied on Wednesday, November 25, 2009

Rocky,

Thanks for the reply.

I am definitely doing that, but I forgot to mention that I am saving a collection, and that the objects that are losing their ids are child objects. Would that make a difference?

_allocations is a BusinessListBase(Of LaborAllocations, LaborAllocation). The client app calls _allocations = _allocations.Save:

-- Class LaborAllocations
Public Overrides Function Save() As LaborAllocations
Return MyBase.Save()
End Function

Protected Overrides Sub DataPortal_Update()

For Each allocation As LaborAllocation In Me
allocation.SourceId = Me.SourceId
allocation = allocation.Save()
Next

End Sub

-- Class LaborAllocation
Public Overrides Function Save() As LaborAllocation
Return MyBase.Save()
End Function

Protected Overrides Sub DataPortal_Insert()
Dim params As SqlParameters = GetUpsertParams()
SqlHelper.ExecuteNonQuery(Config.ConnectionStrings.LaborAllocationConnectionString, CommandType.StoredProcedure, "ALLOCATION_INSERT", params.ToArray)
_id = CInt(params("@Id").Value)
End Sub

RockfordLhotka replied on Wednesday, November 25, 2009

You can't call Save() on a child object. In fact you should get an exception
when trying to do so, and since you aren't getting an exception you are
probably not correctly creating your child objects.

Please review Chapters 3-6 in Expert 2008 Business Objects to see how child
objects should be implemented.

Copyright (c) Marimer LLC