How to serialize into a json from entity?
Asked Answered
N

3

9

I'm trying to serialize an (Entity Framework 6) entity into json. I am making sure the entry is in memory before serializing via the AsNoTracking() method however I get an error as it cant receive a value form a different table that is referenced in the entry.

Inner Exception: When an object is returned with a NoTracking merge option, Load can only be called when the EntityCollection or EntityReference does not contain objects.

Exception: JsonSerializationException:  Error getting value from 'TABLE_X' on 'System.Data.Entity.DynamicProxies....

Code:

List<Location> locations = new DbContext().Locations.Where(x => x.Type == 1).Take(5).AsNoTracking().ToList();
string s = JsonConvert.SerializeObject(locations, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });

All I want to do is return a string of the serialized entity. Im not worried about other objects, solely the locations entity.

When I tried disposing of the connection and then json serializing I received the error: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

I only want to serialize my list, I do not want to return/serialize any foreign dependencies.

N answered 4/11, 2015 at 12:50 Comment(4)
Why do you need to serialize that entity?Thinker
Because I want to store it away in a json file for later. E.g. Unit testing with valid/valuable data.N
I would understand storing POCO classes but now EF entities, but then again you might have different requirements.Thinker
If you specify navigation properties as Virtual you should just be able to serialize the full entity straight out of the Db. No need to turn proxies off or create other models. Alternatively you could eager load all navigation properties?Alvinaalvine
P
7

This an EF's dynamic proxy issue you have to disable it to have your code working

in your class that inherit from DbContext

public class MyModelEntities : DbContext
{
   public MyModelEntities()
   {
      //just disable it like this  
      Configuration.ProxyCreationEnabled = false;
   }
}

Mainly what's happening is that your JsonConvert is trying to serialize an object like this System.Data.Entity.DynamicProxies.Location_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E48E6

due to the proxy, which cannot be found because it's dynamically created

Piccard answered 4/11, 2015 at 12:58 Comment(0)
R
2

You don't need to call AsNoTracking method to load to memory the entities you need. The ToList method is going to do that job.

Now about your issue, is because the JSON serializer is trying to access to each property on an Location instance and you can end up querying for your entire database just because lazy loading is enabled. So, you have two options:

  1. Disable Lazy loading (As @BRAHIMKamel recommended)
  2. Use JsonIgnore atribute over the navigation properties you don't want to be loaded.

Personally, I prefer the first one, and when I need to load a entity with some specific related entity, I use eager loading to load it as part of the query:

context.Locations
       .Include(l=>l.State)//eager loading an hypothetical related entity 
       .Where(x => x.Type == 1)
       .Take(5)
       .ToList();
Rebutter answered 4/11, 2015 at 13:11 Comment(0)
B
1

If your object graph is not too complicated, different approach could be to create simple POCO class, where your Location will be mapped from. Let's say LocationModel. This could be mapped by hand or for example with AutoMapper.

Barcus answered 4/11, 2015 at 13:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.