0

I'm having an issue with Entity Framework where if I include an entity, for instance I have:

  • Entity A that has a foreign key reference to:

  • Entity B

If I run an Entity Framework query and do a .Include("Entity B") my result entity (Entity A) has a property of .Entity B. Ok that's good that's what I expect. BUT!

Entity B then has an Entity A property that is populated which then has an Entity B property that is populated which then has an Entity A property that is populated and it goes on and on and on.

Why is Entity Framework doing this? It seems wasteful and the size of the entity being returned is so much larger due to all the unnecessary materialization of these entities.

Surely I'm missing some setting somewhere. Any ideas guys?

  • 1
    They are just references to each other, both objects live only once. You don't mention in what context you're serializing them. For example [DataContracts have IsReference](http://stackoverflow.com/questions/14161484/datacontract-parent-reference-in-child-property-how-to-avoid-infinite-serializ), or you can [ignore a property or map to a new entity](http://stackoverflow.com/questions/2002940/json-and-circular-reference-exception), and so on. – CodeCaster Mar 02 '15 at 16:04
  • Thanks for the reply. I don't see a "IsReference" property on any of the entities in the .edmx designer. – scubasteve Mar 02 '15 at 16:27
  • So you're saying that as I traverse through in intellisense expanding the entities that they aren't actual copies of the same data but just a reference back to one entity... A -> B -> A -> B -> A -> B So there aren't 3 copies of each but just pointers back to the first "A" and "B"? – scubasteve Mar 02 '15 at 16:28
  • That's exactly it. :) – CodeCaster Mar 02 '15 at 16:29

1 Answers1

0

This behavior works as designed. Technically this is a circular reference.

As CodeCaster mentioned, there're the same objects. A similar result can be simulated with the following source code:

class A {
   public B BReference { get; set; }
}

class B {
   public A AReference { get; set; }
}

static class Program 
{
    [STAThread]
    public static void Main()
    {
        A a = new A();
        B b = new B();
        b.AReference = a;
        a.BReference = b;

        // you should have b.AReference == a and
        // a.Breference == b
    }
}

When loading data from the database the entity framework does the same. It's up to you to ensure that you do not dive too deep into it.

It is always a good idea trying to prevent those scenarios as they will create a lot of trouble (look for circular reference on SO...) especially when using these classes for APIs or serialization.

Anyhow, EF or other mapping tools make use of this construct and it is very convenient while coding.

Community
  • 1
  • 1
Stephen Reindl
  • 5,659
  • 2
  • 34
  • 38