如何从实体序列化为json?

时间:2015-11-04 12:50:57

标签: c# entity-framework entity-framework-6 jsonserializer

我正在尝试将(Entity Framework 6)实体序列化为json。通过AsNoTracking()方法序列化之前,我确保条目在内存中但是我收到错误,因为它无法从条目中引用的另一个表中接收值。

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....

代码:

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

我想做的就是返回一个序列化实体的字符串。我不担心其他对象,只关心位置实体。

当我尝试处理连接然后json序列化时,我收到错误:The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

我只想序列化我的列表,我不想返回/序列化任何外来依赖项。

3 个答案:

答案 0 :(得分:5)

这是EF的动态代理问题,您必须将其禁用才能使代码正常工作

继承自DbContext

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

主要发生的事情是您的JsonConvert正在尝试序列化此类对象System.Data.Entity.DynamicProxies.Location_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E48E6

由于代理无法找到,因为它是动态创建的

答案 1 :(得分:2)

您不需要调用AsNoTracking方法来加载您需要的实体。 ToList方法将完成这项工作。

现在关于您的问题,是因为JSON序列化程序正在尝试访问Location实例上的每个属性,并且您最终可能因为启用了延迟加载而查询整个数据库。所以,你有两个选择:

  1. Disable Lazy loading(正如@BRAHIMKamel推荐的那样)
  2. 在您不想加载的导航属性上使用JsonIgnore属性。
  3. 就个人而言,我更喜欢第一个,当我需要加载具有某个特定相关实体的实体时,我使用eager loading将其作为查询的一部分加载:

    context.Locations
           .Include(l=>l.State)//eager loading an hypothetical related entity 
           .Where(x => x.Type == 1)
           .Take(5)
           .ToList();
    

答案 2 :(得分:1)

如果您的对象图不是太复杂,那么可以使用不同的方法创建简单的POCO类,其中Location将从中映射。让我们说LocationModel。这可以手动映射,例如使用AutoMapper映射。