2014-10-19 56 views
1

我使用EF 6和WebApi 2通过JSON.Net(也称为Newtonsoft)将实体序列化为JSON。WebApi中的实体框架序列化没有急切加载

一切正常,只要我没有嵌套的对象。第二我做到了这一点,并试图拉回每一个孩子的对象。

我使用预先加载(LazyLoadingEnabled = false)和我有类似这样的查询:

return db.Users.Include(user => user.Department).Take(10); 

然而,这些成果的序列化的循环引用结束了。尽管我没有告诉它,但它将整个对象图拉到一起,就好像它是懒加载的,这当然是各种各样的不好的。

例如,尝试序列出:

user.Department.Employees 
user.Department.Managers 
user.Department.Positions 

这当然是不好的,因为这些都是用户......这有部门......这让用户...并在明显结束循环参考循环。

如果我使用JSON序列化的PreserveReferencesHandling.Objects我结束了它检测的参考和添加$ref到JSON输出和输出的数据,但它不应该摆在首位,因为EF不应该加载员工和经理人集合,这会破坏客户端的事情。我试图搞乱ProxyCreationEnabled,但这没有什么区别是真是假。

我尝试使用JSON序列化程序的ReferenceLoopHandling.Ignore,它看起来像它应该检测循环,只是停止序列化,但它进入无限循环。

编辑:这是我的API路线:

// GET: api/User 
    public IQueryable<User> GetPositions() 
    { 
     db.Configuration.ProxyCreationEnabled = false; 
     db.Configuration.LazyLoadingEnabled = false; 
     return db.Users 
      .Include(e => e.Department); 
    } 

而这里的WebApiConfig:

 // Web API routes 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

     var json = config.Formatters.JsonFormatter; 
     json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None; // returns 500 error if "None", returns unwanted data and format if "Objects" 
     config.Formatters.Remove(config.Formatters.XmlFormatter); 

     GlobalConfiguration.Configuration.Formatters.Clear(); 
     GlobalConfiguration.Configuration.Formatters.Add(json); 

更新:我做了ToList上查询的结果,他们最终从我的API返回前呼叫。 EF在到达序列化程序之前加载子对象。

+0

我有同样的挫折感,而且我很少遇到需要反向参考的场景。我不知道他们为什么违反这些不敬虔的周期。对我而言,在设计师模式下,什么对我而言是关闭/标记私人或内部的,反向路径。在子/被引用的表上,有一个关系返回给父代。将它设置为私人或内部,看看是否为你修复它。 – Jason 2014-10-19 23:02:05

+0

当使用AutoMapper和MVC模型不使用EF对象进行序列化时,它适用于我。 – Mariusz 2014-12-17 16:29:55

回答

0

显然,如果我正确理解这是expected behavior。我相信,在跟着更深的链接here后,我很困惑,因为我习惯于使用ObjectContext而不是DbContext

我从我的解决方案的不同方向旋转,并开始展平我的对象,然后从WebApi返回视图或匿名类型,并使用自定义PUTPOST来更新和创建对象。

相关问题