2

When adding a new object to my DbContext, I am getting a nullreferenceexception thrown from inside of Entity Framework.

Stack Trace:

at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.GetOtherEndOfRelationship(IEntityWrapper wrappedEntity)
   at System.Data.Entity.Core.Objects.EntityEntry.AddRelationshipDetectedByForeignKey(Dictionary`2 relationships, Dictionary`2 principalRelationships, EntityKey relatedKey, EntityEntry relatedEntry, RelatedEnd relatedEndFrom)
   at System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInForeignKeys()
   at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChangesInForeignKeys(IList`1 entries)
   at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges()
   at System.Data.Entity.Core.Objects.ObjectContext.DetectChanges()
   at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)
   at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
   at System.Data.Entity.DbSet`1.Add(TEntity entity)

The actual lines of code that causes it:

var convertedFoos = ReadFoosFromForeignSource();    //returns a list of anonymous objects with two fields: Foo Original, Foo Converted
UpdatedFooData(convertedFoos.Where(x => x.Original != null));
var newFoos = convertedFoos.Where(x => x.Original == null).Select(x => x.Converted).ToList();

foreach (Foo newFoo in newFoos)
{
    db.Foos.Add(newFoo);    //error happens here
}

I am reading Foo XML from a foreign source and converting it to local Foo format and then either: updating the existing object or adding the new object to the database.

When the error is thrown (shown by a comment above), db, db.Foos, and newFoo are not null. Inspected newFoo more closely reveals tons of null properties inside of newFoo, but they are all allowed to be null.

Based on the stacktrace I am making the assumption that this is related to collection properties. So I inspected the collection properties more closely and found that none of the collections are null and none of the FK properties of the collection objects are null.

14
  • 1
    is your newFoos object contain any data?, what line are you getting the error on? Commented Aug 6, 2018 at 17:12
  • 1
    I am not an amateur programmer. I know how to debug a null reference exception. As you can see by looking at the stack trace, this null reference exception is happening INSIDE OF ENTITY FRAMEWORK. None of my code is throwing the error. I need someone who is better with entity framework than me to point me in the right direction. Commented Aug 6, 2018 at 17:24
  • 1
    I am not an amateur programmer. <= It's not that I am stating you do not know how to debug an NRE but it is that you did not provide enough information for anyone else to help debug your NRE. The duplicate is there to guide you through it (should you need help) so you can either fix the problem yourself or provide enough detail in your question so that others can help you. Commented Aug 6, 2018 at 17:27
  • 1
    That's fair. Apologies. Just frustrated. I guess I don't see it as MY NRE. Because the error isn't in my code. Or, rather, the exception isn't being thrown from my code. I accept that there is probably something wrong in my code, and it may be that something is being set to null where it shouldn't be. I've been googling and researching this for a week now, I've read over all the stack overflow posts (and some MSDN) that were even remotely relevant. I verified that my PK/FK in my POCOs all line up. I'm just missing... something. Commented Aug 6, 2018 at 17:33
  • 1
    Could you provide an minimal reproducible example? The model definition for Foo, the EF mapping for Foo, as well as basic initialization for Foo (without the copying of state) that would produce the same error. Commented Aug 6, 2018 at 17:37

1 Answer 1

3

Because of the error Entity Framework was throwing and my inability to step into Entity Framework code, I struggled to find the precise error. After some effort I pulled the Entity Framework source code into my project, got it compiling, and debugged the error like I would any other one. I discovered the problem.

I had:

public class Foo
{
    public int Id {get; set;}
    public List<FooBar> FooBars {get;set;}
}

public class Bar
{
    public int Id {get; set;}
    public List<FooBar> FooBars {get; set;}
}

public class FooBar
{
    [Key, Column(Order=1)]
    public int FooId {get; set;}
    public Foo Foo {get; set;}

    [Key, Column(Order=2)]
    public int BarId {get; set;}
    public Bar Bar {get; set;}

    public RelationshipEnum Relationship {get; set;}
}

All of this was to create a relationship between Foo and Bar that also specified the type of relationship.

I was reading data from an external source and creating or updating these relationships. The problem was in my update code:

I was sloppy in determining which FooBar relationship I was updating. If I happened to try to update the wrong one, I was attempting to change one of the composite keys which wasn't allowed.

I fixed this by adding an Id property to my FooBar class and sorting by that to ensure that it was always retrieved from the database in the order it was added. I also had to clear out all old data (I imagine fixing it might have worked, but because I could re-pull it from my foreign source, it was easier to just remove the data and re-pull).

Some extra data I gleaned about how Entity Framework works:

When using the DbSet<T>.Add(T entry) method, it checks for changes in ALL LOADED ENTRIES, not just the one you added, which is why I was getting errors on every single add with no determinable pattern. It was finding the same error in the same Entry for every Entry I tried to add.

TL;DR

My code was trying to change the composite key on an object in a strange way that was causing Entity Framework to choke when validating relationships on all loaded Entries (which it does on every call to add a new Entry).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.