Print Page | Close Window

Many-to-many: Just save the linking object??

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=2667
Printed Date: 03-Jun-2025 at 8:19am


Topic: Many-to-many: Just save the linking object??
Posted By: AuerRo
Subject: Many-to-many: Just save the linking object??
Date Posted: 11-May-2011 at 8:27am
Hi,

I have a many-to-many relationship with no payload. 
According to http://drc.ideablade.com/xwiki/bin/view/Documentation/adding-removing-related-objects#HAdd2829andRemove2829onmany-to-manynavigationproperties - this article in the docs, calling SaveChanges() on the linked entity saves the linking object.

In my application I can only save an entity when it is dirty, so the linking object won't be saved, as the entity stays unchanged when a many-to-many-relation is added. Whereas if i call SaveChanges() on the linked entity, every change beside the linking object will also be saved, and that's something i do not want.

In order to solve this, I have two questions:
  1. Is there a way to determine if a m2m-relation is added to an entity? That could change the "is dirty state".
  2. Or: Is there a way to only save the linking object, without saving the entity's changes?
Thanks for any help in advance!
Roland



Replies:
Posted By: sbelini
Date Posted: 11-May-2011 at 3:42pm

Hi Roland,
 
Not sure what you mean by calling SaveChanges() on the linked entity... do you mean calling a partial save?
SaveChanges(new Entity[] {entityToBeSaved});
 
It that's what you mean, then the linking entity (of a m2m with no payload relation) will also be saved.

 
Please clarify so I can better understand what you are describing.
 
Answering your questions:
1) You can add an EventHandler to the CollectionChanged event of the entity's nav property:
 

employee.Territories.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Territories_CollectionChanged);

 
2) You won't be able to do that in a m2m with no payload linking table. You could do it if you had a m2m with payload... However, you must be aware that you can only call a partial save on the linking table if both entities already exist in the datasource. Otherwise, you must commit the Added entity(ies) as well. (otherwise you will have an exception due to not resolving all temporary IDs)
 
Silvio.


Posted By: AuerRo
Date Posted: 12-May-2011 at 9:11am
Hi Silvio! Thanks for the answer.

Let me clarify the problem by using an example.

I have two entities, Employee and Task, connected m2m without payload; (One Employee can work on many Tasks, on Task can be assigned to many Employees);

If I add or remove a User from Task.Users, how am I able to save that, without saving the Task-Entity itself? Something like SaveChanges(Task.Users); but it seems that this is not possible, or am I wrong?

Questions to your answers of my questions:
1) That's clear. But how do I check if a m2m navigation property changed at all? For example, if i manually restore the collection in the ui to the value it was before the first change, I want the IsDirty-flag to be false. For every dataproperty in an entity, i can take all DataProperties (from EntityAspect.EntityMetadata.DataProperties) and compare property.GetValue(entity, EntityVersion.Original) to property.GetValue(entity, EntityVersion.Proposed);

The problem is, I can't get any EntityVersion with the ListNavigationProperties (EntityAspect.EntityMetadata.ListNavigationProperties), so I can't check if they changed or a change was undone by the user.

2) No question on that. Maybe that would be a solution, just to fake a payload so that I can save the change immediately.

Thanks for your help!
Roland


Posted By: sbelini
Date Posted: 12-May-2011 at 9:47am

Hi Roland,

Thanks for clarifying.
 
Unfortunately, in a m2m with no payload, you will not be able to accomplish this.
 
In this situation, even with a partial save (i.e. SaveChanges(new Entity[] {anEmployee}); or SaveChanges(new Entity[] {aTask}); ) will save the whole Employee-LinkingTable-Task trio.
 
1) technically, if you manually changed the value back to its original, it would actually be a second change rather than a restore. In this case you will need to compare values to determine if it was a restore or another change. Then again, it won't apply on Navigation properties.
You might also consider using RejectChanges:
myEmployee.EntityAspect.RejectChanges();
 
2) a m2m with payload will give you the freedom to manipulate the linking table directly.
 
Silvio.


Posted By: AuerRo
Date Posted: 16-May-2011 at 12:28am
Thanks, that helps me a lot!

1) I absolutely agree, but unfortunately I'm facing clients that would rather undo an edit manually than using a restore-button.

2) That's my way!

Thanks for your help!
Roland

PS: Wouldn't it be a nice feature for a future release to be able to determine if a m2m-relationship changed? It's a bit confusing if I have an EntityManager with changes, but every Entity's EntityState is unchanged.



Print Page | Close Window