Guid changes after emerging from data portal causing delete to fail

Guid changes after emerging from data portal causing delete to fail

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


SethSpearman posted on Monday, October 08, 2007

Hello,

I am writing a CSLA application.  I have built my first object (Meeting) and I have added unit test to test the CRUD functionality.

One of the NUnit tests is called DeleteMeeting and looks like this:
Meeting.DeleteMeeting(_meetingID) 

The other one is called DeleteMeetingByInstance and look like this:
Dim meeting As Meeting
meeting = meeting.GetMeeting(_meetingID)
meeting.Delete()
If meeting.IsSavable Then
    
meeting.Save()
End If

THE Second one(DeleteMeetingByInstance ) is passing. 

The First one (DeleteMeeting) if failing.

The primary key for Meeting is of type GUID.

My debugging of this shows the oddest behavior.  The cause of the error is that the argument that is being passed INTO the portal is not the same one that is emerging from the portal.  So the following line of code will have 'xyz' for the meeting id guid.

Public Shared Sub DeleteMeeting(ByVal meetingID As Guid)

It is passed from there into the CSLA portal.  And emerges from portal into DataPortal_DeleteSelf with the meetingID GUID as 'abc'.  So somewhere in the portal the guid was changed and I can't figure out where or why.

I am having trouble debugging because inside the portal I don't seem to be able to drill down into the value of the criteria object. 

 

Mostly I was wondering if anyone else had seen this and could offer some insight?

 

Thank you

Seth B Spearman

JoeFallon1 replied on Tuesday, October 09, 2007

It sounds to me like you are mixing up deferred deletion with immediate deletion. You did not post all of your code so it is hard to tell.

My Shared method calls DataPortal.Delete (not Delete_Self).

When you call Delete_Self, it creates an instance of the BO and then uses the PK of that instance to delete a record in the DB. So you should only "call" it when your UI has an actual instance available already. That is why .Save works on the BO in your UI.

By calling DataPortal.Delete on the Type, you must pass in a known guid value to your factory method which will then go through the DataPortal as Crtieria and be used to perform the Deletion in the DB.

This is how I have mine set up:

Public Shared Sub DeleteAcct(ByVal acctcode As String)
 
DataPortal.Delete(New CriteriaCode(GetType(Acct), "DeleteAcct", acctcode))
End Sub

Protected Overrides Sub DataPortal_DeleteSelf()
  DataPortal_Delete(
New CriteriaIntegerKey(GetType(Acct), "DataPortal_DeleteSelf", mAcctkey))
End Sub

Protected Overrides Sub DataPortal_Delete(ByVal criteria As Object)
 
Dim strSQL As String

 
If TypeOf criteria Is CriteriaCode Then
   
Dim crit As CriteriaCode = DirectCast(criteria, CriteriaCode)
    strSQL = AcctDAO.Delete(crit.Code)
 
Else
   
Dim crit As CriteriaIntegerKey = DirectCast(criteria, CriteriaIntegerKey)
    strSQL = AcctDAO.Delete(crit.Key)
 
End If

   'tr code removed here
  Try
    'Delete child objects before deleting the parent.
   
DeleteChildren(tr, criteria)

   
'delete the parent
   
DAL.ExecuteNonQuery(tr, CommandType.Text, strSQL)
    PostDeleteData(tr, user)
    
     'tr code removed here
 
Catch ex As Exception
 
   'tr code removed here
  End Try
End Sub

Joe

SethSpearman replied on Tuesday, October 09, 2007

OK,

Here is my code.  The code I posted earlier is from the UnitTests so it is the CALLING code.

But in my BizObjects I have the following code:

This code is on the FRONT of the portal.  It shows guid XYZ in the meetingID param.
***************************

Public Shared Sub DeleteMeeting(ByVal meetingID As Guid)
If Not CanDeleteObject() Then
   Throw New System.Security.SecurityException("User not authorized to remove a Meeting")
End If
DataPortal.Delete(New Criteria(meetingID))
End Sub

*********************************

This code is on the BACK of the portal.  It is showing guid of ABC in the meetingID param
*******************************

#Region " Data Access - Delete "
<Transactional(TransactionalTypes.TransactionScope)> _
Protected Overrides Sub DataPortal_DeleteSelf()
   DataPortal_Delete(New Criteria(_meetingID))
End Sub

<Transactional(TransactionalTypes.TransactionScope)> _
Private Overloads Sub DataPortal_Delete(ByVal criteria As Criteria)
   Using dal As New CslaHelper.Data.DataAccess
      dal.MeetingDelete(_meetingID)
   End Using
End Sub

#End Region ' Data Access - Delete    

 

Hope this helps.

Seth

JoeFallon1 replied on Tuesday, October 09, 2007

This is incorrect.

Private Overloads Sub DataPortal_Delete(ByVal criteria As Criteria)
   Using dal As New CslaHelper.Data.DataAccess
      dal.MeetingDelete(_meetingID)
   End Using
End Sub

It should look a lot more like this:

Protected Overrides Sub DataPortal_Delete(ByVal criteria As Criteria)
  Using dal As New CslaHelper.Data.DataAccess
   
Dim crit As Criteria = DirectCast(criteria, Criteria)
   dal.MeetingDelete(crit.MeetingId)
 End Using
End Sub

You have to use the passed in criteria value for MeetingID not the _meetingID field in the BO.

Joe

SethSpearman replied on Wednesday, October 10, 2007

Joe,

For the record that did the trick.  All my tests run beautifully now.  Thanks for your help.

Seth

Copyright (c) Marimer LLC