我已经为这个问题花了几个星期了。但是我仍然不能解决这个问题。
我在angularjs
中使用http
调用web API服务
$http({
method: 'GET',
url: rootUrl + '/api/Project/ProjectList',
headers: {
'Content-Type': "application/json; charset=utf-8"
}
}).success(function (response) {
$scope.ProjectList = response;
}).error(function (response, errorCode) {
if (errorCode == 444) {
}
})
我把断点放在了服务器端和客户端的代码中。
当我调用该服务时,服务器端方法很快就命中了
我的服务器端方法(使用MVC WEB API和实体框架)
[ActionName("ProjectList")]
[HttpGet]
public IList<Project> ProjectList(Project projectModel)
{
return objIProjectService.ListOfProject();
}
我检查了一下,服务返回了8条记录(数据库中的8行),在objIProjectService.ListOfProject();
这一行中有一个断点。
一切都很顺利。但是我的(响应) http.success and http.error
回调函数的执行速度非常慢。
当我调用http
方法时,请参见下图了解性能
最后,http error function
在5或10分钟后命中,并显示以下错误消息。
System.OutOfMemoryException:'System.OutOfMemoryException‘类型的异常在中引发
这就是问题所在。请告诉我怎样才能解决这个问题?
实际上我为这个问题做了一些事情。
sql server 2008 r2
),那么它正在工作。例如,如果我的数据库表少于7行,那么它的运行速度很快,没有那个错误。但是如果我的表有超过8行,那么它的工作非常慢,并抛出错误??为什么??如果你遇到这个问题,你能分享你的解决方案吗?
发布于 2017-08-23 21:26:48
我认为问题在于序列化程序正在访问项目类上的所有相关属性,所以不是直接返回实体框架类,而是创建一个新类来表示您希望通过api发送的数据(进一步研究DTO类以获取更多信息)
您可以使用dto方法来获取新的Select
类的列表,其中填充了来自EF调用的数据。
var projects = objIProjectService.ListOfProject();
return projects.Select(p => new ProjectDTO() {
ID = p.Id
//... other properties of DTO class
}).ToList();
更好的是,如果您将这个select方法放入EF查询中(即context.projects.Select(/* select info here */).ToList()
,您可以确保EF只返回您需要的字段
在构建API时,请始终检查json/XML响应,确保序列化数据包含您期望它生成的内容。对于实体框架,当它在所有相关的表中导航,取出所有链接的信息,然后尝试将其序列化时,这个响应可能会变得非常庞大。
作为个人偏好,我总是更喜欢返回一个IHttpActionResult
,它允许你管理正在发送回客户端的内容,特别是当出现问题时,控制器有许多方法可以用来创建它,即OK(), BadRequest(), InternalServerError()
...
发布于 2017-08-27 06:37:55
打开Sql Server Profiller并查看EF生成的sql查询和结果。然后尝试execute on sql window this raw查询。也许在这之后你就会明白了。
发布于 2017-08-27 20:22:27
这里的问题是信息的序列化需要很长时间。您正在访问项目类的所有相关类,这可能会在处理内存方面时造成重大损害。
您可以通过两种方式解决此问题:
一种是返回您的承诺,然后获取数据:
return $http({
method: 'GET',
url: rootUrl + '/api/Project/ProjectList',
headers: {
'Content-Type': "application/json; charset=utf-8"
}
}).then(function (response) {
第二个选项将在代码中,使用实体框架或linq查询。
使用select查询来减轻服务器端和客户端的负担,如下所示:
var projectsQuery = from p in ProjectModel as pm where pm.Id = p.Id select p.SomeValue
return projectsQuery
这样,您将能够减轻数据序列化的负担,并可能避免outOfMemoryExcexption。
没有必要在这里打开Sql Profiler,因为来自服务器端的数据是在合理的时间到来的。
https://stackoverflow.com/questions/29999188
复制相似问题