2

I have following models:

public class Category
{
    public virtual ICollection<Product> Products{get;set;}
    public Product()
    {
        Products = new HashSet<Product>();
    }
}

public class Product
{
    public Guid CategoryId{get;set;}
    public virtual Category {get;set;}
}

Now if I execute following statement:

var list = await UoW.Categories.Query.Where(x=>x.Name.Contains("Mob")).ToListAsync();

and return list as JSON from MVC controller action. It throws following exception:

A circular reference was detected while serializing an object of type 
'System.Data.Entity.DynamicProxies.Category_7C2191CFExxxxxxx'.

It is happening because Products collection is not null and each Product in turn contains Category.

What is the reason for virtual properties getting uploaded automatically?

EDIT:- It turns out Json Serializer was accessing properties and causing EF to load them. I have turned LazyLoading off as suggested by haim770.

TheVillageIdiot
  • 38,082
  • 20
  • 126
  • 184
  • Why don't you just apply `[NonSerialized, XmlIgnore]` to the `Category` property in the `Product` class and eliminate the circular reference? – Der Kommissar Apr 22 '15 at 14:17
  • Possible Duplicate of http://stackoverflow.com/questions/2967214/disable-lazy-loading-by-default-in-entity-framework-4 – Anil Apr 22 '15 at 14:17

2 Answers2

1

The reason is the Entity Framework Proxy that is intercepting the access call to your Products property and automatically populates it.

You can explicitly turn Lazy-Loading off though:

context.Configuration.LazyLoadingEnabled = false;

You can also project your Category list into a new list and only populate the desired properties. For example:

var list = await UoW.Categories.Query.Where(x=>x.Name.Contains("Mob"))
                                     .Select(x => new Category {
                                             Id = x.Id,
                                             Name = x.Name
                                     }).ToListAsync();
haim770
  • 45,540
  • 6
  • 91
  • 121
0

WCF tries to walk your objects and serialize the whole object graph. If you have lazy loading enabled (as it is by default), it will get stuck in this circular reference.

One option is to turn off Lazy loading as haim770 suggests. Another is to return Data Transfer Objects rather than returning your EF objects directly.

It is also possible to return your object graph with the circular references intact. However you'll need to create a custom DataContractSerializerOperationBehavior and a custom Attribute to apply that behavior. Sowmy Srinivasan's blog post has the full details.

Robert Graves
  • 2,200
  • 3
  • 19
  • 24