c# - Linq to SQL C#: items between dates
问题描述
I have 2 tables in my SQL server 2012:
Errors (id, cityID, centerID, date)
InspectionVisits (id, cityID, centerID, datePerformed)
I am trying to get the number of errors
between inspection visits
to see if there is an improvement in the center with the specific centerID
and build a chart.
This is my code so far but I can't find out how I can write the where clause to get the number of errors between these inspection visits:
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()
};
Sample Case Something like: 5 errors between Inspection_Visit_1 and Inspection_Visit_2, 2 errors between Inspection_Visit_2 and Inspection_Visit_3 and 1 error between Inspection_Visit_3 and today.
EDIT
Maybe it could work if I show queries per day and mark only the inspection visits in the chart's x axis.
解决方案
我认为这在客户端最容易处理。
首先,您要获取有趣的内容InspectionVisits
并按日期排序,然后转换为 anEnumerable
以将它们拉到客户端:
var orderedIVs = InspectionVisits.Where(iv => iv.cityID == ctid && iv.centerID == centerid).Select(iv => iv.dateperformed).OrderBy(ivdp => ivdp).AsEnumerable();
现在使用一个沿 处理的扩展方法Enumerable
来计算运行值(之所以调用它是Scan
因为它是在 APL Scan 运算符之后建模的,就像Aggregate
返回所有中间值的 an 一样):
// 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 IVPeriods = orderedIVs.Scan((prev, cur) => new { Begin = prev, End = cur }, cur => new { Begin = cur, End = DateTime.Now });
最后,您可以使用期间计算Errors
每个期间之间发生的时间:
var errorsPerIV = IVPeriods.Select(ivp => new { Day = ivp.Begin.Date, Count = Errors.Where(e => ivp.Begin <= e.date && e.date <= ivp.End).Count() });
如果您想在服务器端处理这个,您必须将InspectionVisits
表连接到自身,以便您可以创建期间。我没有用 SQL server 测试过这个:
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() });
推荐阅读
- scala - Log4j 的自定义文件位置:未创建日志
- flutter - 如何修复'错误运行 gradle @ line 24'
- python - 使用术语获取字符的所有组合或排列
- swift - Swift 如何优雅地处理多个按钮 UI?
- python - 熊猫数据框连接后重置组数
- ietf-netmod-yang - config=false 强制节点
- elm - 在 Elm 中组合两个不同的 API 请求
- python - 如果 Python 中不存在 For 循环迭代,则获取空值
- ios - Xcode 能源影响非常高 - iPhone X 上的显示
- mysql - 如何在 group_concat 函数 MYSQL 中使用换行符作为分隔符?