C# Datareader 到 DTO?

标签 c# ado.net 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}

我可以直接从数据库数据对话到DTO吗?例如,我想要类似以下的东西。 (可能还有另外一个数据访问db)

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

这可能吗?如何实现?我希望我能解释一下...

最佳答案

鉴于您的 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);
}

一些注意事项:

  • 我已对您的属性名称进行 Pascal 大小写以遵循 .NET 命名约定
  • 在 LINQ 代码中,您使用 ToArray ,如果您的属性实际上是列表,则实际上不会编译...如果您的属性实际上是数组,则上述方法将不起作用
  • 您可能希望使用单个 List<Tuple<DateTime, double>>,而不是两个单独的列表。甚至创建一个单独的 Reading仅包含日期和值的类。
  • 您可以为 DTO 提供一个接受名称的构造函数,在构造函数中初始化列表,将列表属性设置为只读,并创建一个 AddReading(DateTime, double)方法使调用代码更简洁。

关于C# Datareader 到 DTO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15700075/

相关文章:

c# - `WHERE … IN @xs` ,其中 @xs 参数是一个值列表 : Supported by ADO. NET?

c# - 使用存储过程和 ADO.NET 更新数据库

entity-framework - 如何使用 AutoMapper 将 DTO 映射到 Entity Framework 代理类?

c# - 无法连接kafka集群时无异常

c# - 将正则表达式中的文本更改为大写

c# - order by then count 和 select Max by group,性能问题

c# - SQL 从查询中检测无效的列名

hibernate - RESTful 应用程序中的乐观锁定

validation - 在创建 DTO 期间执行验证之前,NestJS 使用 ValidationPipe 转换属性

c# - 强制 IConfigurationBuilder.Bind() 在绑定(bind)对象失败时抛出错误