Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

वेब एपीआई द्वारा लौटाए गए बड़े JSON डेटा से निपटना

आपकी समस्या यह है कि आप एक Oracle क्वेरी चला रहे हैं जो बहुत बड़ी संख्या में परिणाम लौटा रही है, और फिर उस संपूर्ण परिणाम को HttpResponseMessage पर क्रमबद्ध करने से पहले स्मृति में लोड कर रहा है। .

अपने मेमोरी उपयोग को कम करने के लिए, आपको उन सभी मामलों को ढूंढना और समाप्त करना चाहिए जहां क्वेरी से परिणामों का पूरा सेट अस्थायी मध्यवर्ती प्रतिनिधित्व (उदाहरण के लिए DataTable) में लोड किया गया है। या JSON स्ट्रिंग), और इसके बजाय DataReader . यह यह उत्तर

सबसे पहले, आपके ट्रेसबैक से, ऐसा प्रतीत होता है कि आपके पास है ब्राउज़र लिंक सक्षम करें जाँच की गई। चूंकि यह स्पष्ट रूप से पूरी प्रतिक्रिया को MemoryStream . में कैश करने का प्रयास करता है , आप इसे FilePathResult में बताए अनुसार अक्षम करना चाहेंगे। बड़ी फ़ाइल के साथ OutOfMemoryException फेंका

इसके बाद, आप किसी IDataReader निम्नलिखित वर्ग और कनवर्टर के साथ Json.NET का उपयोग करके सीधे JSON पर:

[JsonConverter(typeof(OracleDataTableJsonResponseConverter))]
public sealed class OracleDataTableJsonResponse
{
    public string ConnectionString { get; private set; }
    public string QueryString { get; private set; }
    public OracleParameter[] Parameters { get; private set; }

    public OracleDataTableJsonResponse(string connStr, string strQuery, OracleParameter[] prms)
    {
        this.ConnectionString = connStr;
        this.QueryString = strQuery;
        this.Parameters = prms;
    }
}

class OracleDataTableJsonResponseConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(OracleDataTableJsonResponse);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("OracleDataTableJsonResponse is only for writing JSON.  To read, deserialize into a DataTable");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var response = (OracleDataTableJsonResponse)value;

        using (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);
                using (var reader = selectCommand.ExecuteReader())
                {
                    writer.WriteDataTable(reader, serializer);
                }
            }
        }
    }
}

public static class JsonExtensions
{
    public static void WriteDataTable(this 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 < reader.FieldCount; i++)
            {
                writer.WritePropertyName(reader.GetName(i));
                serializer.Serialize(writer, reader[i]);
            }
            writer.WriteEndObject();
        }
        writer.WriteEndArray();
    }
}

फिर कुछ इस तरह दिखने के लिए अपना कोड संशोधित करें:

    public HttpResponseMessage Getdetails([FromUri] string[] id)
    {
        var prms = new List<OracleParameter>();
        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 < inconditions.Length; x++)
        {
            sb.Append(":p" + x + ",");
            var p = new OracleParameter(":p" + x, OracleDbType.NVarchar2);
            p.Value = inconditions[x];
            prms.Add(p);
        }
        if (sb.Length > 0)// Should this be inconditions.Length > 0  ?
            sb.Length--;
        strQuery = 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; filename=ProvantisStudyData.json", out contentDisposition))
        {
            response.Content.Headers.ContentDisposition = contentDisposition;
        }
        return response;
    }

यह इन-मेमोरी DataSet . से बचा जाता है परिणामों का प्रतिनिधित्व।

संयोग से, मुझे लगता है कि रेखा

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

इसके बजाय होना चाहिए:

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

मेरा मानना ​​है कि आप क्वेरी में पीछे वाले कॉमा को हटाने की कोशिश कर रहे हैं, जो मौजूद होगा अगर और केवल अगर inconditions.Length > 0

कृपया ध्यान दें - मैं Oracle डेवलपर नहीं हूं और मेरे पास Oracle स्थापित नहीं है। परीक्षण के लिए मैंने OracleClient . का मज़ाक उड़ाया एक अंतर्निहित OleDbConnection . का उपयोग करके कक्षाएं और इसने ठीक काम किया।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle (+) बाहरी जुड़ाव और स्थिर मान

  2. Oracle में क्वेरी सबक्वेरी के साथ चयन करने के लिए

  3. प्रवाह को नियंत्रित करने के लिए विंडोज कमांड स्क्रिप्ट में एसक्यूएल * प्लस का उपयोग कैसे करें?

  4. तृतीय पक्ष Oracle .NET प्रदाताओं की तुलना

  5. VB में Oracle डेटाबेस से कनेक्ट करें