2

データ

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();

これら 3 つの会話の後、私のデータは次のようになります。

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

2 に答える 2

4

datesプロパティとプロパティが変更可能なリストであることを考えるとvalues、一度に行を読み取り (グループ化されていない)、名前でキー付けされた辞書にキーを設定し、日付と値を追加することができます。

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);
}

いくつかのメモ:

  • .NET 命名規則に従うように、プロパティ名を PascalCased にしました
  • あなたが使用ToArrayしたLINQコードでは、プロパティが実際にリストである場合、実際にはコンパイルされません...プロパティが実際に配列である場合、上記のアプローチは機能しません
  • 2 つの個別のリストを使用するのではなく、単一のリストを使用するList<Tuple<DateTime, double>>か、日付と値だけを使用して個別Readingのクラスを作成することもできます。
  • DTO に名前を受け入れるコンストラクターを与え、コンストラクターでリストを初期化し、リスト プロパティを読み取り専用にしAddReading(DateTime, double)、呼び出しコードをよりクリーンにするメソッドを作成することもできます。
于 2013-03-29T09:03:02.917 に答える
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));
}

結果は私の予想です。

どうもありがとう。

于 2013-03-29T15:16:35.833 に答える