0

I have 2 classes within my context, they are as follows;

    public class Supplier
    {
        public int ID { get; set; }
        public virtual ICollection<SupplierOffice> SupplierOffices { get; set; }
    }

    public class SupplierOffice
    {
        public int ID { get; set; }
        public int SupplierID { get; set; }
        public virtual Supplier Supplier { get; set; }

    }       

The relationship is, a supplier has zero or many supplier offices

This context works as expected for the most part; when I want to get a supplier by ID, it returns the supplier populated with all of it's offices

However, what might be a problem is, when I inspect this code in the debugger;

  • I collapse the supplier offices field within a supplier, it is showing many offices
  • I collapse one of the offices to inspect it's properties, and I see it's supplier
  • this supplier then contains offices, offices have a supplier.. and so on

So from what I can tell the system is loading the suppliers and the supplier offices endlessly in a loop. I don't think this is causing any performance issues, so I'm wondering if this is just a quirk of the debugger, and the actual system doesn't do this. If this is looping endlessly, how can I correct this?

Many thanks

Aeptitude
  • 172
  • 2
  • 16
  • 5
    System is not _loading_ suppliers and offices, debugger is showing **the same instance** again and again because of the circular dependency. – Adriano Repetti Jan 05 '18 at 10:23
  • 1
    It's better if you inspect the returned result yourself to find out whether there's real circular dependency, e.g. JSON – zc246 Jan 05 '18 at 10:29
  • 1
    Only when you start a process that traverses the object graph recursively you may run into a StackOverflow exception. One of those processes is serialization, so you have to tell the serializer how to deal with [reference loops](https://stackoverflow.com/q/7397207/861716). – Gert Arnold Jan 05 '18 at 11:02
  • 1
    To help visualize this in complex scenarios, you can right click a variable in the Visual Studio debugger (either in the quick inspect tooltip or any watch window) and pick 'Make object ID'; this will append a symbol like {$1} to the value, and when you come across that same value again you'll see it and know it's the same instance. – Alex Paven Jan 05 '18 at 11:20
  • 1
    And for completeness, Entity Framework is the one that instantiates the objects, and because of its first level cache it will give you the same instance of an object if that object represents the same row in the database. – Alex Paven Jan 05 '18 at 11:22
  • 1
    Do you need the Supplier in SupplierOffice? If not, take a look here, about configuring one-to-many: http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx – Lavinia N. Jan 05 '18 at 12:47

1 Answers1

1

When you navigate in your Debugger, it is nothing else like you are using the navigation property when you are coding:

curSupplier.SupplierOffices 

then e.g.

curSupplier.SupplierOffices[0].Supplier 

then

curSupplier.SupplierOffices[0].Supplier.SupplierOffices

then

curSupplier.SupplierOffices[0].Supplier.SupplierOffices[1].Supplier

There is no recursion here and no endless loop. You are just using the navigation properties, and yes you could use them endless... As the navigation properties are in both directions you could do that and there will be no problem.

As Adriano Repetti wrote in the comments you are always inspecting/accessing the same supplier instance.

MarkusEgle
  • 2,413
  • 4
  • 38
  • 55