C# 存储过程导致JSON响应最小化MVC中的内存使用
我目前有一个MVC web应用程序,我正在尝试创建一个类似API的操作结果。此API方法运行一个存储过程,并以JSON格式返回结果作为响应 问题是,在某些情况下,存储过程返回约6.5k行,所有这些数据都进入我的应用程序的内存并将其销毁。这个数据有很多列,都是必需的 所以我的问题是:有没有一种方法可以运行存储过程并将其结果返回给客户端,而不将整个结果集放入服务器上的内存中?也许我可以获取响应sql流并将其提供给响应流 我的当前代码包含内存泄漏,如下所示:C# 存储过程导致JSON响应最小化MVC中的内存使用,c#,asp.net-mvc,C#,Asp.net Mvc,我目前有一个MVC web应用程序,我正在尝试创建一个类似API的操作结果。此API方法运行一个存储过程,并以JSON格式返回结果作为响应 问题是,在某些情况下,存储过程返回约6.5k行,所有这些数据都进入我的应用程序的内存并将其销毁。这个数据有很多列,都是必需的 所以我的问题是:有没有一种方法可以运行存储过程并将其结果返回给客户端,而不将整个结果集放入服务器上的内存中?也许我可以获取响应sql流并将其提供给响应流 我的当前代码包含内存泄漏,如下所示: public ActionResult G
public ActionResult GetOutletsByHierarchyLevel(string SearchTerm, string Level, bool ReturnAll = false)
{
...
var data = db.CollectionFromSql(
"EXEC [apps].[Rapport_GetOutletsByHierarchyLevel] @SearchTerm,@HierarchyLevel,@ReturnAll",
new Dictionary<string, object>
{{"@SearchTerm", SearchTerm}, {"@Level", Level}, {"@ReturnAll", ReturnAll}}
);
var jsonResult = Json(new JSONResponse()
{
Success = true,
Data = data.ToList().DynamicSQLToDictionary()
});
data = null;
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
如果还有什么我可以提供给你们的,请告诉我。提前感谢您的推荐/文章 您是否具有对存储过程的代码访问权限?
如果是,则可以在sql级别实现分页:。我直接从存储过程返回JSON,然后从API方法返回JSON响应需要sql Server 2016或更高版本。我已经编写了助手方法来调用我的存储过程。此函数调用不带参数的存储过程,并以字符串形式返回JSON数组:
public static string GetDataJSONArray(
string procName,
string connection = null
)
{
if (connection == null)
connection = defaultConnection;
var sql = procName;
StringBuilder sb = new StringBuilder();
using (SqlConnection sqlConnection = new SqlConnection(connection))
{
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(sql, sqlConnection);
cmd.CommandTimeout = defaultTimeout;
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
sb.Append(reader.GetString(0));
}
}
}
var json = sb.ToString();
if (string.IsNullOrWhiteSpace(json))
{
json = "[]";
}
return json;
}
示例程序:
create procedure GetTableRecordCounts
as
begin
select t.name TableName, i.rows RecordCount
from sysobjects t, sysindexes i
where t.xtype = 'U' and i.id = t.id and i.indid in (0,1)
order by RecordCount desc
for json path, INCLUDE_NULL_VALUES
end
go
API方法示例:
[HttpGet]
public HttpResponseMessage GetTableRecordCounts()
{
var jsonString = ProcWrapper.GetDataJSON("GetTableRecordCounts");
HttpResponseMessage success = Request.CreateResponse(HttpStatusCode.OK);
success.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
return success;
}
除非出于某种原因需要,否则我不会反序列化到API方法中的对象。顺便说一句,我目前使用的方法是将JSON对象或数组作为字符串传递到所有需要输入的进程中,如果进程需要返回结果,我总是将JSON对象或数组作为字符串返回。因此,我的进程只有一个参数,比如@JSON nvarcharmax。我喜欢它的简单性。您是否考虑过使用JSON直接获取结果,而不是使用各种对象作为中间形式?漏洞在哪里?指控!但是你有证据吗?6.5公里的划船距离没那么远。如果它真的那么大,那么调用它的应用程序可能也会遇到问题或带宽问题。但是您仍然可以访问Response.OutputStream和Response.Flush,您可以一次循环一行,然后逐个提交json。@madreflection hot dang我不知道这是可能的!!!这是SQL Server 2016中新增的一款全新产品。不过要小心:让存储过程返回特定格式的数据会将其与非常特定的用途联系起来。这将您的数据访问与表示层紧密地结合在一起,并且可能会限制其使用,因此您必须为类似的目的编写多个过程。我认为这是一个好主意。例如,youtube API只发送x行,需要另一个请求才能获取下一个x行。我确实可以访问存储过程的代码,但是此API的目标之一是提供所有数据的综合列表-用于创建电子表格,你的客户应该对你的API做一些请求,然后这个客户把这些部分合并到一个地方。