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.

JaxFirehart
  • 61
  • 1
  • 7
  • 1
    is your newFoos object contain any data?, what line are you getting the error on? – Brad Aug 06 '18 at 17:12
  • If you can provide more information that sheds light on the exact line of code where the exception is thrown as well as additional information about the entities and the state of the entities then we can reopen the question. As it stands now you have to do more research to provide enough details for others to help and the provided duplicate link is a great source for you to use to understand what details to provide, how to get those details, and how to troubleshoot your code. – Igor Aug 06 '18 at 17:15
  • 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. – JaxFirehart Aug 06 '18 at 17:24
  • Try searching on [GetOtherEndOfRelationship(IEntityWrapper](https://www.google.com/search?q=GetOtherEndOfRelationship(IEntityWrapper+site:stackoverflow.com)). One of these might also lead you to the answer you are looking for. – Igor Aug 06 '18 at 17:25
  • 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. – Igor Aug 06 '18 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. – JaxFirehart Aug 06 '18 at 17:33
  • @Igor This question is not a duplicate. There is a downvote button if you think that the question is asked in a bad way or not enough information is provided. Marking it as duplicate of the question you refered it to is simply wrong! – Dominik Aug 06 '18 at 17:35
  • 1
    Could you provide an [mcve]? 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. – Igor Aug 06 '18 at 17:37
  • @JaxFirehart could you please try the following: Put this piece of code just before your foreach loop: newFoos = newFoos.Where(x => x != null).ToList(); – Dominik Aug 06 '18 at 17:37
  • @Dominik Adding .ToList() to the end of that statement didn't change anything, unfortunately. – JaxFirehart Aug 06 '18 at 17:48
  • @Igor I have already tried to do that in order to narrow down my error. I couldn't get a test program to actually throw the error in the same way. Can we unmark this as a duplicate, considering that the question it is marked a duplicate of is not at all the same question? – JaxFirehart Aug 06 '18 at 17:50
  • I have unmarked the duplicate but do not be surprised if others vote to close it for either the same reason or because there is not enough information to help you. I do hope you get the issue resolved though. – Igor Aug 06 '18 at 17:51
  • I **do** appreciate your help @Igor and I am working to my question more minimal, complete, and verifiable. Thanks again. – JaxFirehart Aug 06 '18 at 17:54
  • The problem seems to be from the data model. I think that when inserting this validating an existing relationship between the object that you are going to insert with a ForeingKey (mandatory, I think it is some kind of catalog). Could you show more information about what you want to achieve? – David Romero Tigua Aug 06 '18 at 17:55

1 Answers1

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

JaxFirehart
  • 61
  • 1
  • 7