Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.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# Linq到SQL C:日期之间的项_C#_Linq To Sql - Fatal编程技术网

C# Linq到SQL C:日期之间的项

C# Linq到SQL C:日期之间的项,c#,linq-to-sql,C#,Linq To Sql,我的SQL server 2012中有两个表: 错误id、城市id、中心id、日期 检查访问id、城市id、中心id、执行日期 我正在尝试获取检查访问之间的错误数,以查看使用特定centerID的中心是否有改进,并构建图表 这是到目前为止我的代码,但我不知道如何编写where子句来获取这些检查访问之间的错误数: var errorsPerIV = from e in dc.Errors where e.cityID == ctid && e.c

我的SQL server 2012中有两个表:

错误id、城市id、中心id、日期

检查访问id、城市id、中心id、执行日期

我正在尝试获取检查访问之间的错误数,以查看使用特定centerID的中心是否有改进,并构建图表

这是到目前为止我的代码,但我不知道如何编写where子句来获取这些检查访问之间的错误数:

var errorsPerIV = from e in dc.Errors
                  where e.cityID == ctid && e.centerID == centerid 
                  group e by e.date.Date into g
                  join iv in dc.InspectionVisits on g.FirstOrDefault().cityID equals iv.cityID
                  where iv.centerID == g.FirstOrDefault().centerID
                  select new
                  {
                      Day = g.Key.Day + "/" +
                            g.Key.Month + "/" +
                            g.Key.Year,
                      Errors = g.Count()
                  };
var IVPeriods = orderedIVs.Scan((prev, cur) => new { Begin = prev, End = cur }, cur => new { Begin = cur, End = DateTime.Now });
样本箱 比如:检查访问1和检查访问2之间有5个错误,检查访问2和检查访问3之间有2个错误,检查访问3和今天之间有1个错误

编辑


如果我每天显示查询,并且只在图表的x轴上标记检查访问,可能会起作用。

我不确定是否有更好的方法,但您可以执行以下操作

假设你有一门像这样的课

public class Summary
{
    public DateTime? PreviousInspection;
    public DateTime? NextInspection;
    public int Errors;
}
然后,您可以通过如下查询获得大部分信息

var errorsPerIV = (from e in dc.Errors
                      where e.cityID == ctid && e.centreID == centreid

                      // Find the date of the previous inspection (if any)
                      let previousInspection = (from i in dc.InspectionVisits where i.cityID == e.cityID && i.centreID == e.centreID && i.datePerformed <= e.date orderby i.datePerformed descending select i.datePerformed).FirstOrDefault()

                       // Find the date of the next inspection (if any)
                      let nextInspection     = (from i in dc.InspectionVisits where i.cityID == e.cityID && i.centreID == e.centreID && i.datePerformed >  e.date orderby i.datePerformed ascending  select i.datePerformed).FirstOrDefault()

                      group e by new { previousInspection , nextInspection } into results

                      orderby results.Key.previousInspection 
                      select new Summary
                      {
                          PreviousInspection = results.Key.previousInspection,
                          NextInspection     = results.Key.nextInspection ,
                          Errors             = results.Count()
                      })
                      .ToList();
但是,如果两次访问之间没有错误,那么这些访问将不会出现在您的列表中,因此您需要查找所有访问并查看是否有遗漏,例如

var inspectionsDates = (from i in InspectionVisits where i.cityID == ctid && i.centreID == centreid orderby i.datePerformed select i.datePerformed).ToList();

    for(int i=0; i< inspectionsDates.Count-1; i++)
    {
        if (!errorsPerIV.Any(a=>a.PreviousInspection == inspectionsDates[i]))
        {
            errorsPerIV.Add(new Summary() { PreviousInspection = inspectionsDates[i], NextInspection = inspectionsDates[i + 1], Errors = 0});
        }
    }

我认为这在客户端是最容易处理的

首先,您希望获得感兴趣的InspectionVisitions并按日期排序,然后将其转换为可枚举项以将其拉到客户端:

var orderedIVs = InspectionVisits.Where(iv => iv.cityID == ctid && iv.centerID == centerid).Select(iv => iv.dateperformed).OrderBy(ivdp => ivdp).AsEnumerable();
现在,使用一种扩展方法,沿着可枚举项进行处理,以计算一个运行值,该方法称为扫描,因为它是按照APL Scan运算符建模的,该运算符类似于返回所有中间值的聚合:

// TKey combineFn(T prev, T cur)
// TKey lastKeyFn(T cur)
public static IEnumerable<TResult> Scan<T, TResult>(this IEnumerable<T> src, Func<T, T, TResult> combineFn, Func<T, TResult> lastKeyFn) {
    using (var srce = src.GetEnumerator()) {
        if (srce.MoveNext()) {
            var prev = srce.Current;

            while (srce.MoveNext()) {
                yield return combineFn(prev, srce.Current);
                prev = srce.Current;
            }
            yield return lastKeyFn(prev);
        }
    }
}
最后,通过时段,您可以计算每个时段之间发生的错误:

var errorsPerIV = IVPeriods.Select(ivp => new { Day = ivp.Begin.Date, Count = Errors.Where(e => ivp.Begin <= e.date && e.date <= ivp.End).Count() });

你能提供一个示例案例吗?@Sumitraj我用一个示例案例更新了我的帖子你的代码已经有了where子句-为什么你不能简单地扩展它?@AdrianWragg问题是,我想在两次检查访问之间得到错误,而不是仅仅在检查访问之后。我假设你的查询中有iv而不是mv。检查访问的日期字段是什么?
var orderedIVs = InspectionVisits.Where(iv => iv.cityID == ctid && iv.centerID == centerid).Select(iv => iv.dateperformed).OrderBy(ivdp => ivdp);

var IVPeriods = (from ivb in orderedIVs
                from ive in orderedIVs
                where ivb < ive
                group ive by ivb into iveg
                 select new { Begin = iveg.Key, End = iveg.OrderBy(iv => iv).First() })
                .Concat((from ivb in orderedIVs orderby ivb descending select new { Begin = ivb, End = DateTime.Now }).Take(1));

var errorsPerIV = IVPeriods.Select(ivp => new { Day = ivp.Begin.Date, Count = Errors.Where(e => ivp.Begin <= e.date && e.date <= ivp.End).Count() });