简体   繁体   中英

How to serialize into a json from entity?

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.

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

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();

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM