Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GroupJoin by date,其中第二个列表中的日期介于第一个列表的两个日期之间_C#_.net_Linq - Fatal编程技术网

C# GroupJoin by date,其中第二个列表中的日期介于第一个列表的两个日期之间

C# GroupJoin by date,其中第二个列表中的日期介于第一个列表的两个日期之间,c#,.net,linq,C#,.net,Linq,我有两张桌子: 第一个是时间值(示例) 第二个是逻辑周期 DateFrom | DateTo 12/16/18 | 12/23/18 12/23/18 | 12/30/18 12/30/18 | 01/06/19 01/06/19 | 01/13/19 01/13/19 | 01/20/19 01/20/19 | 01/27/19 01/27/19 | 02/03/19 02/03/19 | 02/10/19 使用Linq将TimeValues表与LogicalPeriods表(时间必须是>D

我有两张桌子:

第一个是时间值(示例)

第二个是逻辑周期

DateFrom | DateTo
12/16/18 | 12/23/18
12/23/18 | 12/30/18
12/30/18 | 01/06/19
01/06/19 | 01/13/19
01/13/19 | 01/20/19
01/20/19 | 01/27/19
01/27/19 | 02/03/19
02/03/19 | 02/10/19
使用Linq将TimeValues表与LogicalPeriods表(时间必须是>DateFrom和新的{period.DateFrom,period.DateTo}进行分组联接需要什么, tv=>tv.time, (period,tv)=>new{period.DateTo,timeValues=tv}//我不知道我需要在这里做什么
我发现,
GroupJoin
只使用相等比较器,但我需要之间的比较。使用方法语法建议解决方案将很有帮助。

使用以下逻辑,我能够获得上面所示的预期结果

CultureInfo provider = CultureInfo.InvariantCulture;
var timeValues = new List<TimeValue>
{
    new TimeValue {time = DateTime.ParseExact("12/28/18","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/03/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/04/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/09/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/15/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("02/03/19","MM/dd/yy",provider), value = 5.6 },
};

var logicalPeriods = new List<LogicalPeriod>
{
    new LogicalPeriod { DateFrom = DateTime.ParseExact("12/28/18","MM/dd/yy",provider), DateTo = DateTime.ParseExact("12/23/18","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("12/23/18","MM/dd/yy",provider), DateTo = DateTime.ParseExact("12/30/18","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("12/30/18","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/06/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/06/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/13/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/13/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/20/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/20/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/27/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/27/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("02/03/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("02/03/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("02/10/19","MM/dd/yy",provider) },
};


var result = logicalPeriods.GroupJoin(timeValues,
    p => p,
    t => logicalPeriods.FirstOrDefault(l => t.time > l.DateFrom && t.time <= l.DateTo),
    (p, times) => new {
        p.DateTo,
        value = times.Count() > 0 ? (double?)times.Sum(t => t.value) : null
    }
);
然而,正如@IvanStoev在评论中提到的

事实(因此答案)是,对于这类问题没有好的标准LINQ解决方案(尽管存在有效的非LINQ算法解决方案)

有了它,我就可以使用

var result = logicalPeriods.Select(p => new 
{ 
    p.DateTo, 
    value = timeValues.Where(t => t.time > p.DateFrom && t.time <= p.DateTo).Sum(t => t.value) 
}).ToList();
var result=logicalPeriods.选择(p=>new
{ 
p、 DateTo,
value=timeValues。其中(t=>t.time>p.DateFrom&&t.time t.value)
}).ToList();

虽然生成与原始解决方案相似的结果,但在处理大型结果集时,这两种方法都不是很有效。

是的,这是LINQ的最佳解决方案。答案清楚地表明,它们都是低效的。喜欢:)@IvanStoev感谢您的反馈。
var TimeValues = new List<TimeValue>
{
    new TimeValue {time = DateTime.Parse("12/28/18"), value = 5.6 },
    new TimeValue {time = DateTime.Parse("01/03/19"), value = 5.6 },
    new TimeValue {time = DateTime.Parse("01/04/19"), value = 5.6 },
    new TimeValue {time = DateTime.Parse("01/09/19"), value = 5.6 },
    new TimeValue {time = DateTime.Parse("01/15/19"), value = 5.6 },
    new TimeValue {time = DateTime.Parse("02/03/19"), value = 5.6 },
};

var LogicalPeriods = new List<LogicalPeriod>
{
    new LogicalPeriod { DateFrom = DateTime.Parse("12/28/18"), DateTo = DateTime.Parse("12/23/18") },
    new LogicalPeriod { DateFrom = DateTime.Parse("12/23/18"), DateTo = DateTime.Parse("12/30/18") },
    new LogicalPeriod { DateFrom = DateTime.Parse("12/30/18"), DateTo = DateTime.Parse("01/06/19") },
    new LogicalPeriod { DateFrom = DateTime.Parse("01/06/19"), DateTo = DateTime.Parse("01/13/19") },
    new LogicalPeriod { DateFrom = DateTime.Parse("01/13/19"), DateTo = DateTime.Parse("01/20/19") },
    new LogicalPeriod { DateFrom = DateTime.Parse("01/20/19"), DateTo = DateTime.Parse("01/27/19") },
    new LogicalPeriod { DateFrom = DateTime.Parse("01/27/19"), DateTo = DateTime.Parse("02/03/19") },
    new LogicalPeriod { DateFrom = DateTime.Parse("02/03/19"), DateTo = DateTime.Parse("02/10/19") },
};

var result = LogicalPeriods.GroupJoin(
    TimeValues,
    period => new { period.DateFrom, period.DateTo },
    tv => tv.time,
    (period, tv) => new {period.DateTo, timeValues = tv })// I don't know what should I need do here
CultureInfo provider = CultureInfo.InvariantCulture;
var timeValues = new List<TimeValue>
{
    new TimeValue {time = DateTime.ParseExact("12/28/18","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/03/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/04/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/09/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("01/15/19","MM/dd/yy",provider), value = 5.6 },
    new TimeValue {time = DateTime.ParseExact("02/03/19","MM/dd/yy",provider), value = 5.6 },
};

var logicalPeriods = new List<LogicalPeriod>
{
    new LogicalPeriod { DateFrom = DateTime.ParseExact("12/28/18","MM/dd/yy",provider), DateTo = DateTime.ParseExact("12/23/18","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("12/23/18","MM/dd/yy",provider), DateTo = DateTime.ParseExact("12/30/18","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("12/30/18","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/06/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/06/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/13/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/13/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/20/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/20/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("01/27/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("01/27/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("02/03/19","MM/dd/yy",provider) },
    new LogicalPeriod { DateFrom = DateTime.ParseExact("02/03/19","MM/dd/yy",provider), DateTo = DateTime.ParseExact("02/10/19","MM/dd/yy",provider) },
};


var result = logicalPeriods.GroupJoin(timeValues,
    p => p,
    t => logicalPeriods.FirstOrDefault(l => t.time > l.DateFrom && t.time <= l.DateTo),
    (p, times) => new {
        p.DateTo,
        value = times.Count() > 0 ? (double?)times.Sum(t => t.value) : null
    }
);
DateTo   | value
12/23/18 | null
12/30/18 | 5.6
01/06/19 | 11.2
01/13/19 | 5.6
01/20/19 | 5.6
01/27/19 | null
02/03/19 | 5.6
02/10/19 | null
var result = logicalPeriods.Select(p => new 
{ 
    p.DateTo, 
    value = timeValues.Where(t => t.time > p.DateFrom && t.time <= p.DateTo).Sum(t => t.value) 
}).ToList();