Updating a many-to-many relation using GraphDiff cause an error

c# ef-code-first entity-framework graphdiff many-to-many

Question

I utilizeEF code first 6.1 with .NET 4 in my application and have the following classes in my model (I removed other irrelevant diagram elements, such asPermission contains additional navigations)enter image description here

I'm using since my business logic functions with detached entitiesRefactorThis.GraphDiff 2.0.1.0 to execute updates. I would like to update aapplicationUserInApplication object, thus I obtain a currentapplicationUserInApplication using itsSecurityRole s from the database and give it back as aView-Model then modify it and remap it toapplicationUserInApplication using Automapper (When updating, I just make little changes.SecurityRoles assortment of anapplicationUserInApplication , theseSecurityRole s previously saved and I only choose them), therefore I specified the settings as follows:

_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 established the mapping forAppUserInApplication in AppUserInApplication_Mapping class:

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);

Following the call,UpdateGraph() whenever I call_dbContext.SaveChange(); The following error occurs:

An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll Additional information: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

[Updated]

I also attempted the mapping.

_dbContext.UpdateGraph(appUserInApplication, map => map
           .AssociatedCollection(t => t.SecurityRoles)
           .AssociatedEntity(t => t.Application)
           .AssociatedEntity(t => t.UserProfile)
           .AssociatedEntity(t => t.AppUser);

But I continue to receive the same error.

Does anyone have any idea where the issue is?

[Updated]

You can download my model's condensed version from https://www.dropbox.com/s/i9dvrb6ebd5wo7h/GraphdiffTest.rar?dl=0.

1
3
10/26/2014 11:10:19 AM

Accepted Answer

The exception indicates that Entity Framework is complaining about the required but unset (null) navigation attributes you've mapped. This was the case for all of your navigation properties, with the exception of security roles, after debugging your sample code.

If you modify your code as follows:

working code

Everything functions as you would expect because the navigation properties are set.

3
10/26/2014 11:35:40 AM

Popular Answer

After reviewing your code, I believe that the issue is with your mappings. In your mappings, you used "OwnedCollection," which should be used in One-To-Many or One-To-One relations; try using the AssociatedCollection instead. The AppUserInApplication table has a Many-To-Many relation with the SecurityRoles table.

  _dbContext.UpdateGraph(appUserInApplication, map => map
            .AssociatedCollection(t => t.SecurityRoles, with=> (....)


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow