sql >> Database teknologi >  >> RDS >> Oracle

Håndtering af store JSON-data returneret af Web API

Dit problem er, at du kører en Oracle-forespørgsel, der returnerer et meget stort antal resultater, og derefter indlæser hele det resultatsæt i hukommelsen, før du serialiserer det til HttpResponseMessage .

For at reducere dit hukommelsesforbrug bør du finde og eliminere alle tilfælde, hvor hele sæt resultater fra forespørgslen indlæses i en midlertidig mellemrepræsentation (f.eks. en Datatabel eller JSON-streng), og i stedet streame dataene ud ved hjælp af en DataReader . Dette undgår at trække alt ind i hukommelsen på én gang ifølge dette svar .

For det første ser det ud til, at du har ud fra din sporing. Aktiver browserlink kontrolleret. Da dette tilsyneladende forsøger at cache hele svaret i en MemoryStream , vil du gerne deaktivere det som forklaret i FilePathResult smidt en OutOfMemoryException med stor fil .

Dernæst kan du streame indholdet af en IDataReader direkte til JSON ved hjælp af Json.NET med følgende klasse og konverter:

[JsonConverter(typeof(OracleDataTableJsonResponseConverter))]offentlig forseglet klasse OracleDataTableJsonResponse{ public string ConnectionString { get; privat sæt; } offentlig streng QueryString { get; privat sæt; } public OracleParameter[] Parametre { get; privat sæt; } public OracleDataTableJsonResponse(streng connStr, string strQuery, OracleParameter[] prms) { this.ConnectionString =connStr; this.QueryString =strQuery; dette.Parameters =prms; }}class OracleDataTableJsonResponseConverter:JsonConverter{ public override bool CanConvert(Type objectType) { return objectType ==typeof(OracleDataTableJsonResponse); } public override object ReadJson(JsonReader reader, Type objectType, object existentValue, JsonSerializer serializer) { throw new NotImplementedException("OracleDataTableJsonResponse er kun til at skrive JSON. For at læse skal du deserialisere ind i en DataTable"); } offentlig tilsidesættelse void WriteJson(JsonWriter writer, objektværdi, JsonSerializer serializer) { var response =(OracleDataTableJsonResponse)værdi; ved hjælp af (var dbconn =new OracleConnection(response.ConnectionString)) { dbconn.Open(); using (var selectCommand =new OracleCommand(response.QueryString, dbconn)) { if (response.Parameters !=null) selectCommand.Parameters.AddRange(response.Parameters); ved hjælp af (var reader =selectCommand.ExecuteReader()) { writer.WriteDataTable(reader, serializer); } } } }}public static class JsonExtensions{ public static void WriteDataTable(denne JsonWriter writer, IDataReader reader, JsonSerializer serializer) { if (writer ==null || reader ==null || serializer ==null) throw new ArgumentNullException(); writer.WriteStartArray(); while (reader.Read()) { writer.WriteStartObject(); for (int i =0; i

Rediger derefter din kode, så den ser sådan ud:

 public HttpResponseMessage Getdetails([FromUri] string[] id) { var prms =new List(); var connStr =ConfigurationManager.ConnectionStrings["PDataConnection"].ConnectionString; var inconditions =id.Distinct().ToArray(); var strQuery =@"SELECT STCD_PRIO_CATEGORY_DESCR.DESCR AS CATEGORY, STCD_PRIO_CATEGORY_DESCR.SESSION_NUM AS SESSION_NUMBER, Trunc(STCD_PRIO_CATEGORY_DESCR.START_DATE) AS SESSION_START_DATE, STCD_PRIO_CATEGORY_DESCR.START_DATE AS SESSION_START_TIME , Trunc(STCD_PRIO_CATEGORY_DESCR.END_DATE) AS SESSION_END_DATE, FROM STCD_PRIO_CATEGORY_DESCR, WHERE STCD_PRIO_CATEGORY_DESCR.STD_REF IN ("; var sb =new StringBuilder(strQuery); for (int x =0; x  0)// Skal dette være inconditions.Length> 0 ? sb. Længde--; strQuer y =sb.Append(")").ToString(); var returnObject =new { data =new OracleDataTableJsonResponse(connStr, strQuery, prms.ToArray()) }; var response =Request.CreateResponse(HttpStatusCode.OK, returnObject, MediaTypeHeaderValue.Parse("application/json")); ContentDispositionHeaderValue contentDisposition =null; if (ContentDispositionHeaderValue.TryParse("inline; filnavn=ProvantisStudyData.json", ud contentDisposition)) { response.Content.Headers.ContentDisposition =contentDisposition; } returnere svar; } 

Dette undgår DataSet i hukommelsen repræsentation af resultaterne.

Jeg regner i øvrigt stregen

 if (sb.Length> 0) sb.Length--; 

i stedet skal være:

 if (inconditions.Length> 0) sb.Length--; 

Jeg tror, ​​du forsøger at fjerne det efterfølgende komma i forespørgslen, som vil være til stede, hvis og kun hvis inconditions.Length> 0

Bemærk venligst - jeg er ikke Oracle-udvikler, og jeg har ikke Oracle installeret. Til test har jeg hånet OracleClient klasser ved hjælp af en underliggende OleDbConnection og det fungerede fint.



  1. MySQL-lagring af flydere

  2. Hvordan verificerer jeg den anvendte objekttype i Oracle fra et objekttypehierarki?

  3. Sådan returneres dagnummeret med et suffiks i MariaDB

  4. Viser * i en tabel