.net JSON序列化需要很长时间
我有两个ViewModels(产品和零件): 现在,这对于I.Take(10)的查询很有效,尽管看起来很慢,但当我尝试序列化1727条记录时,它会陷入困境,五分钟的等待甚至无法完成序列化过程 我尝试使用Json.Net,如下所示:.net JSON序列化需要很长时间,.net,json,asp.net-web-api,serialization,json.net,.net,Json,Asp.net Web Api,Serialization,Json.net,我有两个ViewModels(产品和零件): 现在,这对于I.Take(10)的查询很有效,尽管看起来很慢,但当我尝试序列化1727条记录时,它会陷入困境,五分钟的等待甚至无法完成序列化过程 我尝试使用Json.Net,如下所示: var ret = JsonConvert.SerializeObject(products, new JsonSerializerSettings { Formatting = Formatting.Indented }); 我只是决定尝试使用Json.Net中的
var ret = JsonConvert.SerializeObject(products, new JsonSerializerSettings { Formatting = Formatting.Indented });
我只是决定尝试使用Json.Net中的JsonConvert,因为在我的控制器操作中,当尝试返回JsonResult时,以下将我的对象转换为Json的代码存在同样的效率问题:
return Json(products);
我通过EF Core获得以下产品:
var products = _context.Products.OrderBy(o => o.Name).Where(w => w.IsActive //all products are active
&& (w.Parts.Count(c => c.IsActive) > 0)) //remove parts that are
.Select(pr => new ProductViewModel
{
Id = pr.Id,
Name = pr.Name,
Description = pr.Description,
IsActive = pr.IsActive,
Parts = pr.Parts.OrderBy(o => o.Name).Where(w => w.IsActive) //all parts are active
.Select(prt => new PartViewModel
{
Id = prt.Id,
Name = prt.Name,
IsActive = prt.IsActive,
})
}).ToList();
我能做什么?序列化并不是什么大问题,现在很容易注意到您添加了LINQ查询,问题是糟糕的SQL实体框架将从中生成 首先,您应该使用快速加载将产品表与零件表连接起来。您只需添加一个
Include
方法调用就可以做到这一点
_context.Products.Include(p => p.Parts)
如果未完成此操作,则查询实际上正在执行N+1查询。您应该使用一个简单的技巧来观察您的查询将此代码添加到DbContext
中所执行的实际SQL查询。(仅当您使用EF6时才执行此操作,EF Core会为您查询日志记录。)
执行查询所需时间较长的另一个条件是。其中(w=>w.IsActive&&(w.Parts.Count(c=>c.IsActive)>0))
。我猜EntityFramework正在生成HAVING子句,但如果您发布生成的SQL以优化查询,则会有所帮助
最后,您的Select
方法中的一个微优化是通过更改零件属性获取表达式
// other properties ...
Parts = pr.Parts.Where(w => w.IsActive).OrderBy(o => o.Name),
// other properties ...
这将阻止您的数据库获取和排序非活动部件。请阅读,说明您是如何准确获取
产品的。
。您确定是序列化过程花费了这么长时间吗?另外,您可能希望在服务器上实现某种分页,以避免内存不足。我添加了一个查询@codecaster,因为您说这需要很长时间,那么度量标准是什么?多慢?查询可能不是最优的,但反序列化耗时最长
_context.Products.Include(p => p.Parts)
public YourDBContext()
{
#if DEBUG
this.Database.Log = msg =>
{
Debugger.Log(1, "ALL", "EF DB SQL: " + msg + Environment.NewLine);
};
#endif
}
// other properties ...
Parts = pr.Parts.Where(w => w.IsActive).OrderBy(o => o.Name),
// other properties ...