Removing...

Posts   
 
    
Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 15-May-2006 16:13:56   

I am trying to remove an entity from a collection. For instance...

Dim GroupMember As EntityClasses.SystemGroupMemberEntity GroupMember.GroupId = _GroupEntity.GroupId GroupMember.GroupMemberId = System.Guid.NewGuid GroupMember.UserId = Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("User_ID").Value

                _GroupEntity.Members.Add(GroupMember)

That adds a new Member for the Group. The Primary key is the GroupMemberID. What I need to do next (and this is before I even save the entity) is either remove the group I have just added or any other group by the Group Member ID. Can this be done?

I looked at... Remove, RemoveAt and RemoveIndex but these do not look like they accept the primary key as an option.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 16-May-2006 07:51:56   

Use the Remove() method. And pass an Entity with the PK specified.


CustomerCollection allCustomers = new CustomerCollection();
allCustomers.GetMulti(null);

CustomerEntity customer = new CustomerEntity("CHOPS");
allCustomers.Remove(customer);

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 16-May-2006 12:19:42   
                GroupMemberID = Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("Group_Member_ID").Value
                GroupMember = New EntityClasses.SystemGroupMemberEntity(GroupMemberID)
                _GroupEntity.Members.Remove(GroupMember)

Nope.. Doesnt throw an error but doesn't remove the entity.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 16-May-2006 12:49:37   

GroupMember = New EntityClasses.SystemGroupMemberEntity(GroupMemberID) GroupMember.IsNew=false; // otherwise you will get an instance compare.. _GroupEntity.Members.Remove(GroupMember)

Frans Bouma | Lead developer LLBLGen Pro
Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 16-May-2006 13:25:04   

Nope, nothing happens. Perhaps I should explain something - the Entity that I'm using (GroupEntity) has been brought back from a WebService, the Database isn't local. I used :

GroupMember = New EntityClasses.SystemGroupMemberEntity(GroupMemberID) GroupMember.IsNew=false; // otherwise you will get an instance compare.. _GroupEntity.Members.Remove(GroupMember)

Nothing happened when I removed an existing member and I got a specific cast is invalid if I added a member and then tried to take it off straight away (before saving the entity).

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 16-May-2006 13:30:10   

I'll give you some more of the code. I'm using a Janus Datagrid and in the the CellEditing event for the grid I'm doing .....

Select Case Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("Member").Value

            Case 0

' Remove Member

                GroupMemberID = Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("Group_Member_ID").Value
                GroupMember = New EntityClasses.SystemGroupMemberEntity(GroupMemberID)
                GroupMember.IsNew = False
                _GroupEntity.Members.Remove(GroupMember)

            Case 1

'Add Member GroupMemberID = System.Guid.NewGuid() GroupMember.GroupMemberId = GroupMemberID GroupMember.UserId = Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("User_ID").Value

                _GroupEntity.Members.Add(GroupMember)

                Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("Member").Value = 1
                Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("Group_Member_ID").Value = GroupMemberID

        End Select

If I just add members, all is fine. When I try to remove a member that has just been added (and before I've saved the entity) I get a invalid cast error. If I try to remove a member that was already there, I get no error message but it still doesn't save the member.

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 16-May-2006 13:48:19   

Frustrated... I even tried..

                GroupMemberID = CType(Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("Group_Member_ID").Value, Guid)

                For intLoop = 0 To _GroupEntity.Members.Count - 1
                    If CType(_GroupEntity.Members.Item(intLoop), EntityClasses.SystemGroupMemberEntity).GroupMemberId.ToString = GroupMemberID.ToString Then
                        _GroupEntity.Members.RemoveAt(intLoop)
                        Exit For
                    Else

                    End If
                Next

It finds the match and runs the RemoveAt... but doesn't remove the entity..

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 16-May-2006 13:53:19   

And Set the allowremove to True....

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 16-May-2006 14:56:27   

Ok, if I add the Entity and Remove it with the following code - it removes it if the Entity has not been saved yet. So when the Entity has been saved, it wont include the newly added member (which is correct). However, it will NOT remove an existing entity from the collection....

GroupMemberID = Me.grdGroupMembers.GetValue("Group_Member_ID")
                        Me.grdGroupMembers.SetValue("Group_Member_ID", Nothing)

                        For intLoop = 0 To _GroupEntity.Members.Count - 1
                            If CType(_GroupEntity.Members.Item(intLoop), EntityClasses.SystemGroupMemberEntity).GroupMemberId.ToString = GroupMemberID.ToString Then
                                _GroupEntity.Members.AllowRemove = True
                                _GroupEntity.Members.Item(intLoop).IsNew = False
                                _GroupEntity.Members.RemoveAt(intLoop)

                                Exit For
                            Else

                            End If
                        Next
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 16-May-2006 17:25:45   

What's the stacktrace of the invalid cast exception?

As you're using a webservice, I assume you're using adapter. I couldn't find it in your posts. EntityCollection.Remove(entity) will first do: int index = EntityCollection.IndexOf(entity).

This thus means that if YOU do: GroupMemberID = Me.grdGroupMembers.SelectedItems(0).GetRow.Cells("Group_Member_ID").Value GroupMember = New EntityClasses.SystemGroupMemberEntity(GroupMemberID) Dim index as Integer = _GroupEntity.Members.IndexOf(GroupMember)

it should give a value >= 0. If not, it can't find the entity and remove will then thus not work.

The IndexOf routine uses Entity.Equals. Equals does a PK compare between two entities if BOTH are not new. If one is new or both are new, an instance compare is performed. An instance compare always fails in your case as the entity you compare with is new, hence my IsNew=false remark.

In the scenario with a non-new entity, the PK has to be the same, as a PK compare is performed.

Frans Bouma | Lead developer LLBLGen Pro
Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 16-May-2006 19:32:58   

I fixed the invalid cast, my mistake - it was due to the event I picked in the janus control.

With your code I get -1...whether its a saved Member or not.

There is:

SystemGroupEntity SystemGroupMemberEntity

A SystemGroupEntity HAS a PK of GroupID A SystemGroupEntity HAS Members (SystemGroup.GroupID > SystemGroupMember.GroupID). A SystemGroupMemberEntity has PK of GroupMemberID

So, when I use _GroupEntity.Members.Remove (GroupMember) I am doing:

SystemGroupEntity.Members.Remove (SystemGroupMemberEntity ).

I can't see what the problem is...

Could it be a problem with the prefetch I'm doing on the server side to bring back the GroupEntity?..

This is code for that.

        Dim prefetchPath As IPrefetchPath2 = New PrefetchPath2(CType(EntityType.SystemGroupEntity, Integer))
        prefetchPath.Add(SystemGroupEntity.PrefetchPathMembers).SubPath.Add(SystemGroupMemberEntity.PrefetchPathUser)

        prefetchPath.Add(SystemGroupEntity.PrefetchPathPermissions)

        Dim GroupToReturn As New SystemGroupEntity(sGroupID)
        Dim adapter As New DataAccessAdapter

        adapter.FetchEntity(GroupToReturn, prefetchPath)

        Return GroupToReturn

I'm returning a SystemGroupEntity.

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 17-May-2006 03:22:30   

I'm going to try and state what the current issue is and see if this is a helps.

You can successfully use remove(entity) now if the entity has not been saved to the database, but it is not working when the entity has already been committed to the database.

When you say Remove(entity) it is not working when the entity has already been committed to the database do you mean that it is not removed from the collection or that it has not been removed from the database?

After an entity is saved to a database it must be deleted from the database, removing it from a collection have no affect on the entity in the database. This may not be your issue, but many people make this assumption and so I thought it worth mentioning.

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 17-May-2006 09:53:13   

"After an entity is saved to a database it must be deleted from the database, removing it from a collection have no affect on the entity in the database. This may not be your issue, but many people make this assumption and so I thought it worth mentioning. "

eh? I thought removing it from the collection and doing a SaveEntity (which happens on the server once the object is sent back) would know to delete the entity I removed from the collection , much like Adding an Entity saves it to the database. ... Is this not the case?

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 17-May-2006 10:01:43   

Because it is indeed removing it from the collection... I did..

msgbox _groupentity.members.count.tostring

Before and after the Remove...

It correctly reduced by 1.

However, saving the entity didnt remove the entity. Is this "by design". I find it strange that you can add an entity and have it saved to the database but cannot remove it. What is the way around this ?

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 17-May-2006 10:10:02   

On the Server, the GroupEntity is sent back and....

        Dim adapter As New DataAccessAdapter

        Try

            adapter.SaveEntity(sGroupEntity)
            Return True
        Catch ex As Exception
            Return False
        Finally

        End Try

That saves the Entity.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 17-May-2006 11:08:47   

Coolcoder wrote:

"After an entity is saved to a database it must be deleted from the database, removing it from a collection have no affect on the entity in the database. This may not be your issue, but many people make this assumption and so I thought it worth mentioning. "

eh? I thought removing it from the collection and doing a SaveEntity (which happens on the server once the object is sent back) would know to delete the entity I removed from the collection , much like Adding an Entity saves it to the database. ... Is this not the case?

No, that's not the case. This is by design. You have to remove an entity explicitly with delete statements, like DeleteEntity().

The reason for this is that removing an entity from a collection can mean different things: - you want to remove the entity from the set because you want to process a subset of the entities in the set - you want to remove the entity from the db

This, together with the fact that removing an entity is very drastic and thus implicit deletes should be impossible, it's been designed that deletes have to be executed explicitly.

It's easy to combine saves and deletes though. Use a unitofwork object: add the entities to delete to that object as well as the save actions.

Sorry for not telling you this earlier, we couldn't figure out if you were under the assumption that removing the entity from the collection would remove it from the db as well.

Frans Bouma | Lead developer LLBLGen Pro
Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 17-May-2006 11:18:29   

I see.

So in my example, what code would I need to use to send the entity back to the server to perform the delete? I should read up on UnitOfWork, I haven't touched that at all.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 17-May-2006 14:38:30   

what code would I need to use to send the entity back to the server to perform the delete?

Option 1: if you want to delete one entity at a time then explicitly call DeleteEntity

adapter.DeleteEntity(YourEntity);

Option 2: if you want to keep track of the entities to be deleted and then delete them at once, then you might add them to a new collection and then call DeleteEntityCollection

adapter.DeleteEntityCollection(CollectionToBeDeleted);

Option 3: use a UnitOfWork object, which might look the same as option 2, but it lets you also add entities for insert and entities for update. Please refer to the LLBLGen Pro documentation "Using the generated code -> Adapter -> Unit of work and field data versioning"

Coolcoder
User
Posts: 37
Joined: 22-Sep-2005
# Posted on: 17-May-2006 15:42:41   

With option 2, can I add different entities into the collection - e.g GroupMemberEntity, TeamMemberEntity etc.. then call the DeleteEntityCollection once on the server?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 17-May-2006 15:54:13   

Yes you can