2016-08-10 7 views
0

Oracle Databaseに問合せを行い、結果をJSON形式で戻すWeb APIを作成しました。返されるデータが非常に大きい場合、例外外の問題が発生します。したがって、questionでは、結果セット全体をメモリにロードしてからHttpResponseMessageにシリアル化する前に問題が発生していることが示唆されました。Web APIから結果セットをシリアライズ

だから

[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)) 
     { 
      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(); 
    } 
} 

以下のクラスを作成し、APIコントローラは

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 (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=PStudyData.json", out contentDisposition)) 
    { 
     response.Content.Headers.ContentDisposition = contentDisposition; 
    } 
    return response; 
} 

私はAPIを呼び出すときに問題は今、それは例外で例外がclass OracleDataTableJsonResponseConverter内にあるエラーがスローされています文using(var reader = selectCommand.ExecuteReader())を言ってinvalidOperationException Connection must be open for this operation

私はすべての接続文字列が表示されている正しく渡さそれが問題に何ができるかenter image description here

は、私がASP.NETオラクル接続に新しいですし、私は一種のここにこだわって、以下のようなサーバーバージョンでエラーがスローされます。どんな助けも大いにありがたいです

+0

これらの単純なことを接続状態、パラメータ、結果マッピングとして解決するマイクロORM(Dapperなど)をお勧めします。手動で処理する必要はありません。 – Husqvik

答えて

1

明示的に接続を開く必要があります。

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

    using (var dbconn = new OracleConnection(response.ConnectionString)) 
    { 
     dbconn.Open(); 
     ... 
    } 
} 
関連する問題