New Posts New Posts RSS Feed: Add and Remove
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Add and Remove

 Post Reply Post Reply
Author
danjal View Drop Down
Groupie
Groupie


Joined: 20-Sep-2010
Posts: 43
Post Options Post Options   Quote danjal Quote  Post ReplyReply Direct Link To This Post Topic: Add and Remove
    Posted: 17-Nov-2010 at 4:08am

We have a database table called EntUser.

The table contains, among others, the fields: p_userID and p_isGroup.

The table contains our users and groups, and p_isGroup determines whether the entity is a user or group.

 

What users that are in what groups is determined in an second table called EntUserGroups.

This table has two fields: p_userID and p_groupID

 

Ideablade Entity model gives us the opportunity to see what groups a user is in by this statement:

p_currentUser.p_userGroups;

 

And what users that are in a group:

p_currentGroup.p_users;

 

p_currentUser and p_currentGroup are of type EntUser.

P_userGroups and p_users are of type IdeaBlade.EntityModel.RelatedEntityList<EntUser>

 

On my UI, I have two ListBoxes: one shows all groups and the second shows the groups that a current user is in. Between these ListBoxes are two buttons: Add and Remove.

When I add or remove a group to/from the current users groups, a Save button shall become enabled – this works fine by looking at the entitymanager.EntityChanged event.

 

The code behind the Add button looks something like this:

protected void OnAddGroup(EntUser newValue)

        {

            p_currentUser.p_userGroups.Add(newValue);

            p_currentUser.EntityAspect.SetModified();

        }

 

This works fine, but I have to use SetModified to trigger the entitymanager.EntityChanged event.

My question here: is this the right way to do this?

 

The code behind the Remove button looks something like this:

protected void OnRemoveGroup(EntUser newValue)

        {

            p_currentUser.p_userGroups.Remove(newValue);

            p_currentUser.EntityAspect.SetModified();

        }

 

This does not remove the group from p_userGroups. I get this exception when I save:

Entity Save Error: System.Data.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. at System.Data.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected, UpdateCommand source) at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at IdeaBlade.EntityModel.Edm.EdmSaveExecutor.ProcessSaves(IEnumerable`1 groupsByType) at IdeaBlade.EntityModel.Edm.EdmSaveExecutor.SaveWithinContext() at IdeaBlade.EntityModel.Edm.EdmSaveExecutor.Save(DataSourceResolver dataSourceResolver, IDataSourceKey dsKey, SaveWorkState workState)

 

I then changed my Remove method to something like this:

protected void OnRemoveGroup(EntUser newValue)

        {

            var i = p_currentUser.p_userGroups.IndexOf(newValue);

            p_currentUser.p_userGroups i .EntityAspect.Delete();

            updateGroupIdsForUser();

        }

 

But this actually deletes the group from the EntUser database table J

My question here: how do I remove a group from p_userGroups and save the changes?

 


Edited by danjal - 19-Nov-2010 at 2:28am
Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post Posted: 19-Nov-2010 at 5:46pm

Hi danjal,

Changes to collections related to an entity don't cause the entity to be changed because no field on the entity is itself changing.
For instance, in a one to many relashionship Customer_Order if you do:
 
aCustomer.Orders.Add(anOrder);
 
aCustomer will keep the entity aspect as Unchanged, while anOrder will be set to Modified since the FK, which is a scalar property, (CustomerID) was changed.
 
In this case, instead of manually changing EntityState to trigger an event, you should be watching the CollectionChanged event:
 
p_currentUser.p_userGroups.CollectionChanged += (s, e) => {
  if (e.Action == NotifyCollectionChangedAction.Add) {
    // Do something
  } else if (e.Action == NotifyCollectionChangedAction.Remove) {
    // Do something
  }
};
 
 
Regards,
   sbelini.
Back to Top
danjal View Drop Down
Groupie
Groupie


Joined: 20-Sep-2010
Posts: 43
Post Options Post Options   Quote danjal Quote  Post ReplyReply Direct Link To This Post Posted: 21-Nov-2010 at 11:21am

Thanx sbelini,

I will look into this.

 

I have been reading this documentation regarding adding and removing in the collection:

http://drc.ideablade.com/xwiki/bin/view/Documentation/CreatingEntities#HAddingandRemovingRelatedObjectsusingAdd2829andRemove2829

 

As I say, it works to add to the collection, but I get an exception when removing and saving. Why do I get this exception?

 

Entity Save Error: System.Data.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries. at System.Data.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected, UpdateCommand source) at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at IdeaBlade.EntityModel.Edm.EdmSaveExecutor.ProcessSaves(IEnumerable`1 groupsByType) at IdeaBlade.EntityModel.Edm.EdmSaveExecutor.SaveWithinContext() at IdeaBlade.EntityModel.Edm.EdmSaveExecutor.Save(DataSourceResolver dataSourceResolver, IDataSourceKey dsKey, SaveWorkState workState)

Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post Posted: 22-Nov-2010 at 9:59am
Hi danjal,
 
The concurrency exception occurs because you are trying to save an entity that seems to be modified previously by another entity manager or client. (i.e. the value of the field "holding" the concurrency strategy in the datasource is not the same as the value in your entity when it was initially loaded from the datasource)
 
If you are using cuncurrency strategy, you must handle these concurrency conflicts. (for instance, update your entity to the most current state, according to datasource, before making changes and saving)
 
You can find more information on concurrency in our DevForce Resource Center. There is also an example located here.
 
Silvio.
Back to Top
danjal View Drop Down
Groupie
Groupie


Joined: 20-Sep-2010
Posts: 43
Post Options Post Options   Quote danjal Quote  Post ReplyReply Direct Link To This Post Posted: 08-Dec-2010 at 12:43pm

I have been looking at the links regarding the concurrency issues – but I do not know what I am supposed to do J

I am debugging the application up against a database that is only used by me – so there should not be any concurrency problems.

 

I have done something similar as described above, but where the many-to-many relations are in a table that has a “payload” and therefore exists as a type in my entity model. This works fine.

Here is my code for the add and remove methods, which work fine:

        protected void OnRemoveGroup(EntPointGroupAccess newValue)

        {

            newValue.EntityAspect.Delete();

            p_groupsWithAccess = null;

        }

 

        protected void OnAddGroup(EntUser newValue)

        {

            var tmp = C2NetDomainModelEntityManager.DefaultManager.CreateEntity<EntPointGroupAccess>();

            tmp.p_userID = newValue.p_userID;

            tmp.p_customerID = m_pointGroup.p_customerID;

            tmp.p_pointGrID = m_pointGroup.p_pointGrID;

            tmp.p_readWrite = 3;

            tmp.EntityAspect.AddToManager();

            p_groupsWithAccess = null;

        }

 

I am now thinking of making the table that contains the many-to-many relations between users and groups, into a “payload” table has a workaround.

 

Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down