3

让我们看看你能不能帮助我。我不太擅长 LINQ,所以我什至不知道这是否可能。实际上,我认为是,但我还没有找到最好的方法。

我有一个具有列表和数据表的对象。此 DataTable 的行数与列表中的项目数相同,并且它们是相关的(列表中的第一项与第一行相关,第二项与第二行相关,依此类推)。我希望能够从 DataTable 中选择一个日期范围及其相关行。我目前正在这样做,但它有一些循环和一个 IndexOf,我需要很长时间来处理。你们对我如何使它更快有什么建议吗?

这基本上是对象的结构(我已经简化了一点,但重要的是这里):

public class CustomObject(){
    public List<DateTime> dates { get; set; }
    public DataTable table { get; set; }
}

这是我选择它的方式:

private bool SelectRange(DateTime begin, DateTime end, CustomObject custom)
{
    var range = from date in custom.dates
                where date.CompareTo(begin) >= 0 &&
                      date.CompareTo(end) < 0
                select date;

    DataTable tmpTable = custom.table.Copy();  // I'm doing this just to copy the structure of the DataTable
    tmpTable.Clear();

    if (range.Count() > 0)
    {
        List<DataRow> rowList = new List<DataRow>();
        foreach (var date in range)
        {
            int dateIndex = custom.dates.IndexOf(date);
            rowList.Add(custom.table.Rows[dateIndex]);
        }

        foreach (DataRow row in rowList)
        {
            tmpTable.Rows.Add(row.ItemArray);
        }
        custom.table = tmpTable;
    }
    else
    {
        custom.table.Rows.Clear();
    }                    
}

您对如何优化它有任何想法吗?

非常感谢您的关注。任何想法都将受到欢迎(也欢迎对我的非母语英语进行更正)。

4

2 回答 2

2

如果您想让事情变得更简单,请使用.Zip()将您的两个独立列表转换为一个相关列表。

var newList = custom.dates.Zip(custom.table.Rows, 
  (first, second) => new { Date = first, Row = second });

一旦你有了它,你就可以在每个日期/行对上做一个简单的选择:

var reducedList = newList.Where(i => i.Date >= begin && i.Date <= end);

之后,您可以将该简化列表添加到您的数据表中。

(我没有编译或测试以上)

于 2013-06-06T20:49:00.067 回答
1

DataTable.Copy复制 table + data的结构。我假设您只想使用空表复制结构(列)(因为DataTable.Clear无论如何您都要执行)。因此使用DataTable.Clone

DataTable tmpTable = custom.table.Clone(); 

但是,您根本不需要它CopyToDataTable。您可以在比行索引更合适的日期列上加入两个集合:

var rows = from dt in range
           join row in custom.table.AsEnumerable()
           on dt equals row.Field<DateTime>("DateColumn")
           select row;
DataTable newTable = rows.CopyToDataTAble();

为什么 LINQ JOIN 比使用 WHERE 链接快得多?

如果您坚持索引链接,我将使用此查询而不是第二个索引查找:

int[] indices = custom.dates
    .Select((dt, index) => new{dt,index})
    .Where(x => x.dt >= begin && x.dt < end)
    .Select(x => x.index)
    .ToArray();
var newTable = custom.table.AsEnumerable()
    .Where((row, index) => indices.Contains(index))
    .CopyToDataTable();

旁注:而不是range.Count() > 0你应该使用range.Any(). Enumerable.Count即使您只想知道是否至少有一个结果,也需要执行整个查询才能获得总数。因此Enumerable.Any,请尽快使用中断。

if(range.Any())
{
    // ...
}
于 2013-06-06T20:53:07.763 回答