2013-12-11 2 views
-1

저는 통계 목적으로 데이터를 추출하고 처리하는 것을 목표로하는 프로젝트를 진행하고 있습니다. 많은 요소 "E"가 있고 각 요소에 {F1, F2, F3, ...} 필드 목록이 있다고 가정 해 보겠습니다. 내 주요 표는 다음과 같습니다 : 나는 키와 같은 "날짜"와 데이터 테이블에 elementId로부터으로 데이터를 추출 할 필요가하나의 차트에 여러 그래프를 그리기 위해 데이터 테이블로 데이터를 추출하십시오.

enter image description here

.

[{"key": "date1", 
"F1": "value", 
"F2": "value"} 
,{"key": "date2", 
"F1": "value", 
"F2": "value"} 
,{"key": "date3", 
"F1": "value", 
"F2": "value"} 
,{....}] 

나의 현재 구현은 다음 다음을 수행입니다 :

1) 쿼리 데이터베이스 필드와 순서에 따라 날짜하여 Dictionary<DateTime, double>

2) 확인하고 각 Dictionary에서 누락 된 값을 입력합니다.

3) 목록 또는 Dictionary 키로 반복하고 DataRow 행을 입력하십시오.

나는 이것이 궁극적 인 해결책이라고 생각하지 않는다. 나는 코드를 최적화하려고 노력해왔다. 그러나 필자는 초점을 맞추어야하는 계층에서 정말로 확신 할 수 없다. 데이터베이스에서 선택을 사용하여 필요한 구조를 얻을 수있는 가능한 방법이 있습니까 (추가 루프 필요 없음)?

+1

_data의 table_는 DataTable' 및 _main table_는 데이터베이스 테이블 또는도 메모리''이다 DataTable' 수단? –

+0

예, 메인 테이블에서 내 데이터베이스에 존재하는 것을 의미했습니다. DataTable의 경우 차트 용 Javasript API에 전달하기위한 구조가 필요합니다. – mahoosh

답변

0

그러나 분명히 밝혀진 것은 DateTime의 날짜 부분으로 그룹화하고이 날짜가 키이고 값이 List<double> 인 사전을 선택한다고 가정합니다.

그럼 DataTable이 필요하지 않습니다. double 대신 모든 속성을 가진 사용자 정의 클래스를 사용합니다.

public class ElementMeasurement 
{ 
    public Element Element { get; set; } 
    public double Value { get; set; } 
    public string Field { get; set; } 
    public DateTime Date { get; set; } 
} 

public class Element 
{ 
    public int ElementID { get; set; } 
    public string Name { get; set; } 
} 

지금 당신이 Enumerable.GroupBy을 사용할 수 있습니다 System.Linq의 일부입니다 : mainTable 이미 원시 데이터와 DataTable이라고 가정하면

Dictionary<DateTime, List<ElementMeasurement>> dateMeasurements = mainTable.AsEnumerable() 
    .GroupBy(row => row.Field<DateTime>("Date").Date) 
    .ToDictionary(g => 
     g.Key, 
     g => g.Select(row => new ElementMeasurement 
      { 
       Element = new Element { ElementId = row.Field<int>("ElementId") }, 
       Field = row.Field<string>("Field"), 
       Value = row.Field<double>("Value"), 
       TimeOfMeasurement = row.Field<DateTime>("Date") 
      }).ToList() 
); 

편집 : "그럼 난 당신이 알고 있도록한다 행 수천 마일의 거대한 테이블입니다! "

테이블이 아직 메모리에 없다는 것을 알지 못했습니다. 그렇다면 이것은 너무 비싼 메모리 일 수 있습니다. DataReader에서 Date에 의해 정렬 된 행을 생성하는 루프가 더 효율적일 수 있습니다. 그런 다음 위 클래스를 사용하여 읽기 쉽고 유지 관리가 가능하지만 사전을 단계별로 채울 수 있습니다. 예를 들어

(가정-SQL 서버)

var dateMeasurements = new Dictionary<DateTime, List<ElementMeasurement>>(); 
using(var con = new SqlConnection("ConnectionString")) 
using (var cmd = new SqlCommand("SELECT e.* FROM Elements e ORDER BY Date,ElementId,Field,Value", con)) 
{ 
    con.Open(); 
    using (var rd = cmd.ExecuteReader()) 
    while(rd.Read()) 
    { 
     DateTime timeOfMeasurement = rd.GetDateTime(rd.GetOrdinal("Date")); 
     DateTime dateOfMeasurement = timeOfMeasurement.Date; 
     List<ElementMeasurement> measurements = null; 
     if (!dateMeasurements.TryGetValue(dateOfMeasurement, out measurements)) 
     { 
      measurements = new List<ElementMeasurement>(); 
      dateMeasurements.Add(dateOfMeasurement, measurements); 
     } 
     var measurement = new ElementMeasurement 
     { 
      Element = new Element { ElementId = rd.GetInt32(rd.GetOrdinal("ElementId")) }, 
      Field = rd.GetString(rd.GetOrdinal("Field")), 
      Value = rd.GetDouble(rd.GetOrdinal("Value")), 
      TimeOfMeasurement = timeOfMeasurement 
     }; 
     measurements.Add(measurement); 
    } 
} 
+0

코드를 이해했다면 mainTable.AsEnumerable()을 메모리에로드하고 있습니까? 그럼 수천 마일의 행이있는 거대한 테이블이라는 사실을 알려야합니다! – mahoosh

+0

@mahoosh : 나는 그 테이블이 이미 기억에 없다는 것을 알지 못했다. 그렇다면 이것은 너무 비싼 메모리 일 수 있습니다. 그래서'Data'에 의해 정렬 된 행을 생성하는'DataReader'의 루프가 더 효율적입니다.그렇다면 여전히 위의 클래스를 사용하여 읽기 쉽고 유지할 수 있지만 'Dictionary' \t을 단계별로 채울 수 있습니다. –

+0

@mahoosh : 샘플을 제공하기 위해 내 대답을 편집했습니다. –

관련 문제