Updating many-to-many relationship using GraphDiff results in an error
I use EF code first 6.1
with .NET 4
in my application and have the following classes in my model (I cut out other unrelated parts of the diagram, for example Permission
has other navigation features):
My business logic works with separate objects, so I use RefactorThis.GraphDiff 2.0.1.0
to perform updates. I want to update an object applicationUserInApplication
, so I get an existing one applicationUserInApplication
with it SecurityRole
from the database and return it as View-Model
, and then I update it and map it applicationUserInApplication
with using Automapper
(in I am only modifying the SecurityRoles
collection applicationUserInApplication
, these are SecurityRole
saved earlier and I only select them), so I defined the following configuration:
_dbContext.UpdateGraph(appUserInApplication, map => map
.OwnedCollection(t => t.SecurityRoles, with=>
with.AssociatedCollection(t=>t.Permissions)
.AssociatedEntity(t => t.ApplicationDescriptor))
.AssociatedEntity(t=>t.ApplicationDescriptor)
.AssociatedEntity(t=>t.AppUser)
.AssociatedEntity(t=>t.UserProfile));
and the following mapping is defined for AppUserInApplication
in class AppUserInApplication_Mapping
:
this.HasRequired(t => t.AppUser).WithMany(t => t.AppUserInApplications).HasForeignKey(d => d.AppUserId);
this.HasRequired(t => t.Applicationdescriptor).WithMany(t => t.AppUserInApplications).HasForeignKey(d => d.ApplicationId);
this.HasMany(t => t.SecurityRoles).WithMany(t => t.AppUserInApplications)
.Map(m =>
{
m.ToTable("AppUserInApplicationSecurityRole");
m.MapLeftKey("AppUserInApplications_Id");
m.MapRightKey("SecurityRoles_Id");
});
this.HasRequired(t => t.UserProfile).WithMany().HasForeignKey(t=>t.UserProfileId);
After the call above UpdateGraph()
, when I call _dbContext.SaveChange();
, I get the following error:
An unhandled exception of type "System.InvalidOperationException" occurred in EntityFramework.dll Additional information: Operation failed: The relationship could not be changed because one or more foreign key properties are not null. When a relationship change occurs, the corresponding foreign key property is set to zero. If the foreign key does not support null values, a new relationship must be defined, a different non-null value must be assigned to the foreign key property, or the unrelated object must be deleted.
[Update]
I also tried the following display
_dbContext.UpdateGraph(appUserInApplication, map => map
.AssociatedCollection(t => t.SecurityRoles)
.AssociatedEntity(t => t.Application)
.AssociatedEntity(t => t.UserProfile)
.AssociatedEntity(t => t.AppUser);
But I am getting the same error.
Does anyone know where the problem is?
[Update]
I downloaded a simplified version of my model, you can get it from https://www.dropbox.com/s/i9dvrb6ebd5wo7h/GraphdiffTest.rar?dl=0
source to share
An exception means that the Entity Framework is complaining about navigation properties that you rendered as needed but not set (they are zero). After debugging your sample code, this was done for all of your navigation properties except for security roles.
If you change your code like this:
The navigation properties are set and everything works as you expect.
source to share
I looked at your code and I think the problem is with your mappings. The AppUserInApplication table has a Many-to-Many relationship to the SecurityRoles table, and in your mappings you used "OwnedCollection" - which should be used in a one-to-many or one-to-one relationship, try using AssociatedCollection instead.
_dbContext.UpdateGraph(appUserInApplication, map => map
.AssociatedCollection(t => t.SecurityRoles, with=> (....)
source to share