简体   繁体   English

如何从实体序列化为json?

[英]How to serialize into a json from entity?

I'm trying to serialize an (Entity Framework 6) entity into json. 我正在尝试将(Entity Framework 6)实体序列化为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. 通过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....

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. 当我尝试处理连接然后json序列化时,我收到了错误: 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 这是EF的动态代理问题,您必须禁用它以使代码正常工作

in your class that inherit from DbContext 在您的类中继承自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 主要是发生的事情是你的JsonConvert正在尝试序列化像这样的对象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. 您无需调用AsNoTracking方法即可将所需实体加载到内存中。 The ToList method is going to do that job. ToList方法将完成这项工作。

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

  1. Disable Lazy loading (As @BRAHIMKamel recommended) 禁用延迟加载 (建议使用@BRAHIMKamel)
  2. Use JsonIgnore atribute over the navigation properties you don't want to be loaded. 在您不想加载的导航属性上使用JsonIgnore属性。

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. 如果您的对象图不是太复杂,那么不同的方法可能是创建简单的POCO类,其中您的Location将从中映射。 Let's say LocationModel . 让我们说LocationModel This could be mapped by hand or for example with AutoMapper. 这可以手动映射,例如使用AutoMapper映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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