Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / WCF

Solution to: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable

5.00/5 (2 votes)
12 Apr 2013CPOL2 min read 45.8K  
This is a solution to The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable.
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.

Problem Description

The error quoted above happened to me after I started using AutoMapper on my WCF service for updating my entities. Previously, I had a "manual map" to passing the properties that I received on my data contract to the entity that I got on my context and update it. When we decided to implement AutoMapper on our project, my mapping code started like this:

PHP
Mapper.CreateMap<MyDataContract, MyEntity>.IgnoreAllNonExisting();

Since all my properties were named the same on both classes, everything seemed to be easy peasy.

But sadly, I started getting the error message:

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.

This message was driving me crazy, because of the text I was thinking that I was making something wrong with the FK relationships on the Database, or in someway the field was being passed null without being null on the contract, or somebody changed the table in someway (yeah sure, blame others :-P). After some deep look into the code (including debugging line by line all the updating process), I found the error.

Since I'm copying the modified values (from DataContract to Entity) when mapping, I'm passing all the values from one instance to the other. This sounds OK, right? I mean, I want all my changes to be persisted on the database.

Well, is not that easy. Since my contract comes from a web application, when saving there I don't have all the navigation properties. When this is the case and I just map all, I'm also mapping and overwriting the values of this navigation properties, that in this case are null on my DataContract. This makes the Entity to update the ForeignKey Columns that belong to that navigation property to be null too. That is why the error says that you're sending null values, because actually you are.

Solution

Since the problem is that we're mapping null navigation properties, and we actually don't need them to be updated on the Entity since they didn't changed on the Contract, we need to ignore them on the mapping definition:

PHP
ForMember(dest => dest.RefundType, opt => opt.Ignore())

So my code ended up like this:

PHP
Mapper.CreateMap<MyDataContract, MyEntity>
ForMember(dest => dest.NavigationProperty1, opt => opt.Ignore())
ForMember(dest => dest.NavigationProperty2, opt => opt.Ignore())
.IgnoreAllNonExisting();

And voilĂ ! the problem is solved.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)