2011-04-12 6 views
1

에서 동적 차원의 가변 배열을 반환합니다. 현재 C#/WCF 데이터 서비스에서 OLAP 큐브 쿼리의 결과를 반환하는 서비스를 만들려고합니다. OLAP 결과가 직렬화되는 방식, 클라이언트가 인증/승인 된 방식, 웹 사이트의 자바 스크립트에서 큐브를 직접 쿼리 할 수있는 방법을 완벽하게 프로그래밍 방식으로 제어하기 위해이 작업을 수행하고 있습니다.C# WCF 서비스

OLAP 쿼리의 결과에는 실제 크기로 1 ~ 5 개의 숫자가 포함될 수 있습니다. 내가 가지고있는 문제는 내가 사용할 수있는 모든 차원의 처리를 하드 코딩하지 않고 동적 인 차원의 배열을 지그재그 배열로 만드는 방법을 알아낼 수 없다는 것입니다. 따라서 첫 번째 퀘스트는 C#에서 동적 차원의 가변 개수 배열을 만드는 우아한 방법이 있습니까?

일단 동적 차원의 배열이 있으면 DataContractJsonSerializer (또는 자유롭게 사용할 수있는 다른 json serializer)를 사용하여 json으로 직렬화 할 수 있습니까?

DimensionMemberCaptions 각 차원 (OLAP 멤버 이름) 및 데이터 헤더를 포함
{ 
    "DimensionMemberCaptions" = [["Dim1 member1", "Dim2 member2"], ["Dim2 member1"], ["Dim2 member2"]], 
    "Data" = [[1, 2], 
      [3, 4]], 
    "FormatedData = [["1$", "2$"], 
        ["3$", "4$"]] 
} 

/formateddata은 결과의 테이블 : 목표는 2 차원 결과를 다음과 같이 보입니다 객체에이 직렬화하는 것입니다 .

나는 자신의 직렬화 함수를 작성하는 것을 피하고 싶지만, 시간이 지남에 따라 더 매력적으로 보입니다 - 지그재그 대신 Array (다차원 배열)를 사용하고 OLAP을 직렬화하기 위해 특별히 json serializer를 작성했습니다 WCF REST 메서드에서 반환 된 Stream으로 출력합니다.

+0

그냥 조금 더 추가, 입력이 가변 배열 할 수에 대한 실제 요구 사항이 없다 - 단지로 출력 위와 같이 형성 될 수있다. 그들은 데이터 계약자 직렬화기에 의해 직렬화되지 않았기 때문에 다차원 배열을 보지 않았다. 또한 플랫폼은 .net 3.5입니다. –

답변

4

Adomd에 더 구체적으로 문제를 해결할 수있는 방법을 찾았습니다. 그러나 Adomd에 의존하지 않고도 동일한 기술을 적용하여 해결할 수 있습니다. Newtonsoft의 Json 직렬화 라이브러리 (http://james.newtonking.com/projects/json-net.aspx)를 사용합니다. 이것으로 Adomd CellSet (기본적으로 다차원 OLAP 쿼리의 결과)을 직렬화하는 자체 'JsonConverter'를 만들 수 있습니다. 이는 치수의 수에 관계없이 작동합니다.

public class CellSetConverter : JsonConverter 
{ 

    public override bool CanRead 
    { 
     get 
     { 
      return false; 
     } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     if (objectType == typeof(CellSet)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     CellSet cellSet = (CellSet)value; 
     int cellCount = cellSet.Cells.Count; 
     int[] axisCounts = new int[cellSet.Axes.Count]; 
     int[] currentIndex = new int[cellSet.Axes.Count]; 
     for (int i = 0; i < axisCounts.Length; i++) 
     { 
      axisCounts[i] = cellSet.Axes[i].Positions.Count; 
     } 

     for (int i = 0; i < cellSet.Axes.Count; i++) 
     { 
      writer.WriteStartArray(); 
     } 

     for (int i = 0; i < cellCount; i++) 
     { 
      serializer.Serialize(writer, cellSet[currentIndex].Value); 
      currentIndex = IncrementIndex(writer, currentIndex, axisCounts); 
     } 
    } 

    string[] GetCaptions(CellSet cellSet, int[] index) 
    { 
     string[] captions = new string[index.Length]; 
     for (int i = 0; i < index.Length; i++) 
     { 
      Axis axis = cellSet.Axes[i]; 
      captions[i] = axis.Positions[index[i]].Members[0].Caption; 
     } 

     return captions; 
    } 

    int[] IncrementIndex(JsonWriter writer, int[] index, int[] maxSizes) 
    { 
     bool incremented = false; 
     int currentAxis = 0; 
     while (!incremented) 
     { 
      if (index[currentAxis] + 1 == maxSizes[currentAxis]) 
      { 
       writer.WriteEndArray(); 
       index[currentAxis] = 0; 
       currentAxis++; 
      } 
      else 
      { 
       for (int i = 0; i < currentAxis; i++) 
       { 
        writer.WriteStartArray(); 
       } 

       index[currentAxis]++; 
       incremented = true; 
      } 

      if (currentAxis == index.Length) 
      { 
       return null; 
      } 
     } 

     return index; 
    } 
} 

그리고 WCF REST 서비스

가 함께 갈 :

[ServiceContract] 
public class MdxService 
{ 
    const string JsonMimeType = "application/json"; 
    const string connectionString = "[Data Source String]"; 
    const string mdx = "[MDX query]"; 

    [OperationContract] 
    [WebGet(UriTemplate = "OlapResults?session={session}&sequence={sequence}")] 
    public Stream GetResults(string session, string sequence) 
    { 
     CellSet cellSet; 
     using (AdomdConnection connection = new AdomdConnection(connectionString)) 
     { 
      connection.Open(); 
      AdomdCommand command = connection.CreateCommand(); 
      command.CommandText = mdx; 
      cellSet = command.ExecuteCellSet(); 
     } 

     string result = JsonConvert.SerializeObject(cellSet, new CellSetConverter()); 
     WebOperationContext.Current.OutgoingResponse.ContentType = JsonMimeType; 
     Encoding encoding = Encoding.UTF8; 
     byte[] bytes = encoding.GetBytes(result); 
     return new MemoryStream(bytes); 
    } 
}