【问题标题】:Datatables / Enumerated Lists, C# and calculating difference between two numbers数据表/枚举列表、C# 和计算两个数字之间的差异
【发布时间】:2016-10-06 16:10:29
【问题描述】:

我是 C# 中的 DataTables 和枚举列表的新手。我已经查找了很多帮助,但似乎无法解决这个问题,这是.... 我有一个简单的表格 Dates,Code,Price 将代码视为股票代码。我实际上是在尝试计算此日期和下一个日期之间的回报或价格变化,即特定代码的日期 t+1 /日期 t。然后将其添加回表中。

我不确定数据表或枚举集是要走的路,但我首先尝试使用数据表,下面的设置可以创建表:

private static DataTable GetData(dynamic Dataset)
{
    DataTable tbl = new DataTable();

    tbl.Columns.Add("EvalDate", typeof(DateTime));
    tbl.Columns.Add("Code", typeof(string));
    tbl.Columns.Add("Price", typeof(double));
    tbl.Columns.Add("Return", typeof(double));

    for (int irow=2;irow<Dataset.GetLength(0); irow++)
    {
        if (Dataset[irow,1] == null) { break; }
        DateTime EvalDate = DateTime.FromOADate((double)(Dataset[irow, 1]));
        string code = (string)(Dataset[irow, 2]); 
        double price = (double)Dataset[irow,3];                

        tbl.Rows.Add(EvalDate,code,price,null);

    }

    return tbl;

}

但我随后尝试使用列表来解决问题:

var Dataset = getRng("A1:E50000", "Data");
DataTable tbl = GetData(Dataset);   
var uniquecodes = (from items in tbl.AsEnumerable()
                select items["Code"]).Distinct().ToList();
List<object> Running = new List<Object>();

    foreach (var code in uniquecodes)
    {
        var ts = (from items in tbl.AsEnumerable()
                  orderby items.Field<DateTime>("EvalDate")
                  where items.Field<string>("Code") == (string)code
                  select items);

        ts.ElementAt(0).SetField<double>("PriceRet", 1);

        for (int idx = 1; idx < ts.Count(); idx++)
        {

            double price0 = ts.ElementAt(idx - 1).Field<double>("Price");
            double price1 = ts.ElementAt(idx).Field<double>("Pice");
            double delta = price1 / price0;

            ts.ElementAt(idx).SetField<double>("PriceRet", delta);                       

        }
        Running.Add(ts);

它没有崩溃,但速度慢且效率低,令人绝望。

数据如下所示:

我的 SQL 知识很好,但我努力将其转化为上面的可行代码。任何帮助将不胜感激。

所以我达到了预期的结果,但是通过 SQL.... 我使用了以下语句/查询:

select  row_number() over (partition by[Code] order by [EvalDate]) [Id], 
        [Evaldate], [Code], [Price]

into #TEMP
from  MyTable

where  Code in ('AAA','BBB','CCC'); -- The list of codes to calc the return for ...

select T1.[EvalDate],T1.[Code],T1.[Price]/T.[Price] as [Delta]
from    #TEMP T1
        inner join #TEMP T
            on T1.Id = T.Id +1
            and T1.Code = T.Code 

drop table #TEMP

然后,这正确地给了我一个未透视的列表,其中包含每个日期更改的适用价格变化。

我原以为 DataTable 会像 SQL 一样简单快捷?

【问题讨论】:

    标签: c# sql datatables enumerated-types


    【解决方案1】:

    阅读此question 的答案。您的代码使用动态对象,这总是使这变慢。我想你会发现你的GetData() 函数是瓶颈,如果你可以重构你的代码以便你可以传递GetData 一个静态已知的数据类型,它会运行得更快。

    【讨论】:

    • 嗨 Alistair - 感谢您提供链接和参考 - 这无疑有助于我理解“动态”。我的问题虽然与我将动态数据集转换为 tbl 然后基本上通过枚举列表进行枚举有关。我相信虽然我对枚举列表缺乏了解是主要原因。再次感谢。
    猜你喜欢
    • 2020-02-09
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    相关资源
    最近更新 更多