2013-03-29 38 views
2

DATAC#數據讀取器到DTO?

Name | Value | Date | 

cat1 |  3 | date1 | 
cat1 |  5 | date2 | 
cat1 |  2 | date5 | 
cat2 |  6 | date8 | 
cat2 |  7 | date1 | 
cat2 |  2 | date6 | 

DTO

public class MeterReadingsChartData 
{ 
    public string name { get; set; } 
    public List<DateTime> dates { get; set; } 
    public List<double> values { get; set; } 
} 

轉換

// first, I fetching datas from db to dataTable 
// second, I convert to datatable to another object list 
// for example IEnumerable<Readings> readings 
// third, like following; one more conversation too 
var chartSeries = readings.GroupBy(x => new { x.Name }) 
        .Select(g => new 
        { 
         name = g.Key.Name , 
         values = g.Select(x => x.Value).ToArray(), 
         dates = g.Select(x => x.Date).ToArray() 
        }).ToArray(); 

這三個談話以後,我的數據是這樣的:

cat1: { values: {3 ,5, 2}, dates: {date1, date2, data5} 
cat2: { values: {6 ,7, 2}, dates: {date8, date1, data6} 

我可以直銷從db數據到DTO的對話。例如,我想要像下面這樣的事情。 (可能有另一個數據訪問db)

IEnumerable<MeterReadingsChartData> MeterReadingsChartData; 
while (reader.Read()) 
{ 
    // fill chart data DTO 
} 

是否可能和如何?我希望,我可以解釋......

回答

4

鑑於您的datesvalues特性是可變的列表,你可以只在一個時間(羣組)讀取一行,並重點通過名稱鍵入一個字典,加入日期和值你去:

var readings = new Dictionary<string, MeterReadingsChartData>(); 
while (reader.Read()) 
{ 
    string name = reader.GetString(0); 
    DateTime date = reader.GetDateTime(1); 
    double value = reader.GetDouble(2); 

    MeterReadingsChartData group; 
    if (!readings.TryGetValue(name, out group)) 
    { 
     group = new MeterReadingsChartData { 
      Name = name, 
      Values = new List<double>(), 
      Dates = new List<DateTime>() 
     }; 
     readings[name] = group;  
    } 
    group.Values.Add(value); 
    group.Dates.Add(date); 
} 

的幾個注意事項:

  • 我PascalCased你的屬性名遵循.NET命名約定
  • 在你的LINQ的代碼你已經使用ToArray,WH ICH不會實際編譯如果你的屬性是真的列出...如果你的屬性實際上是陣列中,上面的方法是行不通的
  • 不是有兩個單獨的列表,你可能需要使用一個單一的List<Tuple<DateTime, double>>甚至創造一個單獨的Reading類只有一個日期和一個值。
  • 你可以給你的DTO構造函數接受的名字,在構造函數初始化列表,使列表屬性爲只讀,並創建一個AddReading(DateTime, double)方法使調用代碼清潔。
+0

答覆大感謝,如果我有一個更道具,例如「單元」,然後可以予補充一點:'讀數[單位] =基團;'? –

+0

@AliRızaAdıyahşi:不,可能不是 - 關鍵是'name'是關鍵。您可能會將'Unit = unit'放入'group'的對象初始值設定項中。 –

+0

我嘗試做你的建議,我像下面添加它,謝謝... –

0

@JonSkeet,我嘗試做你的建議一樣以下,和它的作品。但我不知道下面的代碼是完全一樣的建議...

DTO

public class MeterReadingsChartData 
{ 
    public string Name { get; set; } 
    public string TypeName { get; set; } 
    public string Unit { get; set; } 
    public List<Tuple<DateTime, double>> DateAndValue { get; set; } 

    public MeterReadingsChartData(string name, List<Tuple<DateTime, double>> dateAndValue, string typeName, string unit) 
    { 
     this.Name = name; 
     this.DateAndValue = dateAndValue; 
     this.TypeName = typeName; 
     this.Unit = unit; 
    } 
} 

數據讀取和轉換

var readings = new Dictionary<string, MeterReadingsChartData>(); 

while (reader.Read()) 
{ 
    string name = reader.GetString(5); 
    DateTime date = reader.GetDateTime(1); 
    double value = reader.GetDouble(2); 
    string typeName = reader.GetString(3); 
    string unit = reader.GetString(4); 

    MeterReadingsChartData group; 
    if (!readings.TryGetValue(name, out group)) 
    { 
     group = new MeterReadingsChartData(name, new List<Tuple<DateTime, double>>(), typeName, unit); 
     readings[name] = group; 
     readings[typeName] = group; 
     readings[unit] = group; 
    } 
    group.DateAndValue.Add(new Tuple<DateTime, double>(date, value)); 
} 

結果我的預期。

非常感謝。