【问题标题】:C# Datareader to DTO?C# Datareader 到 DTO?
【发布时间】:2013-03-29 08:50:58
【问题描述】:

数据

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
}

有可能吗?怎么做?我希望,我可以解释...

【问题讨论】:

    标签: c# ado.net dto


    【解决方案1】:

    鉴于您的 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,如果您的属性确实是列表,则实际上不会编译...如果您的属性实际上是数组,则上述方法将不起作用
    • 您可能希望使用单个 List&lt;Tuple&lt;DateTime, double&gt;&gt;,甚至创建一个单独的 Reading 类,而不是两个单独的列表,而只使用一个日期和一个值。
    • 您可以为您的 DTO 提供一个接受名称的构造函数,在构造函数中初始化列表,将列表属性设为只读,还可以创建 AddReading(DateTime, double) 方法以使调用代码更简洁。

    【讨论】:

    • 非常感谢您的回复,如果我还有一个道具,例如“单元”,那么我可以添加这个:readings[unit] = group; 吗?
    • @AliRızaAdıyahşi:不,可能不是——关键是name 是关键。您可能会将 Unit = unit 放在 group 的对象初始化器中。
    【解决方案2】:

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

    结果是我的预期。

    非常感谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-11
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多