Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 使用Lambda、Linq和实体框架选择值的更改_C#_Linq_Lambda - Fatal编程技术网

C# 使用Lambda、Linq和实体框架选择值的更改

C# 使用Lambda、Linq和实体框架选择值的更改,c#,linq,lambda,C#,Linq,Lambda,我有以下实体框架类定义: class TimeValue { DateTime StartDate; double Value; } 假设给定以下一系列值,我只想知道值何时更改: 2000-01-01 100 2000-01-15 100 2000-02-01 110 2000-02-15 120 2000-03-01 120 2000-03-15 50 2000-04-01 50 2000-04-15 50 2000-05-01 120 因此,结果将是:

我有以下实体框架类定义:

class TimeValue
{
    DateTime StartDate;
    double Value;
}
假设给定以下一系列值,我只想知道值何时更改:

2000-01-01  100
2000-01-15  100
2000-02-01  110
2000-02-15  120
2000-03-01  120
2000-03-15  50
2000-04-01  50
2000-04-15  50
2000-05-01  120
因此,结果将是:

2000-01-01  100
2000-02-01  110
2000-02-15  120
2000-03-15  50
2000-05-01  120
我可以使用lambda/linq精细地选择值。然后,我使用以下代码迭代结果以添加到列表中:

var timeValueQuery = _context.TimeValues.Where(...);

List<TimeValue> timeChanges = new List<TimeValue>();
TimeValue lastValue = null;
foreach (var tvq in timeValueQuery)
{
    if (lastValue == null || tvq.Value != lastValue.Value)
    {
        timeChanges.Add(tvq);
    }
    lastValue = tvq;
}
var timeValueQuery=\u context.TimeValues.Where(…);
List timeChanges=新列表();
TimeValue lastValue=null;
foreach(timeValueQuery中的var tvq)
{
if(lastValue==null | | tvq.Value!=lastValue.Value)
{
时间变化。添加(tvq);
}
lastValue=tvq;
}

只是想知道是否有更快捷/更好的方法。再次阅读数据集后编辑

我看分组是行不通的。理想情况下,您希望在db服务器上使用此逻辑,而不是由于网络io等原因而在客户端

您可以将其作为过程或动态sql编写。动态sql在短期内可能更容易实现

简单方法,将其选择到光标中。循环到临时表变量中并返回结果集


如果您的数据集非常小,那么请使用现有的易于阅读的linq循环。除非你需要,否则不要增加复杂性。i、 e.不要进行微优化。

您可以创建扩展方法,该方法仅在满足某些条件时才会返回项目。此条件(谓词)将接受两个参数—previous和current item,它应该比较这两个参数:

public static IEnumerable<T> TakeIf<T>(this IEnumerable<T> source, 
                                       Func<T, T, bool> predicate)
{
    var enumerator = source.GetEnumerator();
    if (!enumerator.MoveNext())
        yield break;

    yield return enumerator.Current;
    T previous = enumerator.Current;

    while (enumerator.MoveNext())
    {
        T current = enumerator.Current;
        if (predicate(previous, current))
            yield return current;

        previous = current;
    }
}

不知道这是否更好:)无论如何:

IQueryable值=…;//在这里初始化
var query=从v输入值
其中(从v2开始,以值为单位)
orderby v2.StartDate
其中v2.StartDate>v.StartDate
选择v2.Value).FirstOrDefault()!=v、 价值观
选择v;

如果可能为零值,请将FirstOrDefault()更改为FirstOrDefault(不可能的值)。同样,对于cycle,它可能更有效(但您要求的是LINQ)。

这不起作用-如果它两次更改为相同的值,它将只给您最后一个值。@Andez感谢:)顺便说一句,我还要添加检查源是否为null,以避免NullReferenceExceptionSlever。只需确保数据是有序的。
var timeChanges = _context.TimeValues.TakeIf((x, y) => x.Value != y.Value);
  IQueryable<TimeValue> values = ...; // initialize here
  var query = from v in values
              where (from v2 in values
                     orderby v2.StartDate
                     where v2.StartDate > v.StartDate
                     select v2.Value).FirstOrDefault() != v.Value
              select v;