我希望有人能够在这里指导我正确的方向......
public class SubmissionLog
{
public int PKId {get;set;}
public int SubmissionId {get;set;}
public DateTime Created {get;set;}
public int StatusId {get;set;}
}
这是数据:
1, 123, '1/24/2013 01:00:00', 1
2, 456, '1/24/2013 01:30:00', 1
3, 123, '1/25/2013 21:00:00', 2
4, 456, '1/25/2013 21:30:00', 2
5, 123, '2/25/2013 22:00:00', 1
6, 123, '2/26/2013 21:00:00', 2
7, 123, '2/16/2013 21:30:00', 1
我想要的是: 我想知道某一天从StatusId 1到StatusId 2的平均时间跨度。
所以,让我们说日期是2013年2月26日,那么如果我第一次得到这样的列表,那么我认为会有意义:
var endlingList = (from sl in db.SubmissionLogs
where (DateTime.Now.AddDays(days).Date == sl.Created.Date) // days = passed number of days to make it 2/26/2013
&& (sl.StatusId == 2)
select sl).ToList();
var endingLookup = endlingList.ToLookup(a => a.SubmissionId, a => a.Created); // thought of using lookup because Dictionary doesn't allow duplicates
之后我想我会找出起点
var startingList = (from sl in db.SubmissionLogs
where endingList.Select(a => a.SubmissionId).ToArray().Contains(sl.QuoteId)
&& sl.StatusId == 1
select sl).ToList();
然后我所做的就是:
var revisedList = endingLookup.Select(a =>
new SubmissionInterval {
SubmissionId = a.Key,
EndDateTime = endingLookup[a.Key].FirstOrDefault(), //This is where the problem is. This will only grab the first occurance.
StartDateTime = startLookup[a.Key].FirstOrDefault() //This is where the problem is. This will only grab the first occurance.
});
然后我要做的是获得平均值(再次,这将仅包括状态1的初始或第一次发生以及某些提交ID提交日志的状态2):
return revisedList.Count() > 0 ? revisedList.Select(a=> a.EndDateTime.Subtract(a.StartDateTime).TotalHours).Average() : 0;
所以,我希望有人会先了解我的问题是什么......重新上限,我希望在每个状态1和2之间获得时间间隔。我将日期传入,然后我必须看看因为这确保了我会找到1的。如果我走了另一条路并寻找1,那么2可能不存在(不管怎样都不想这样)。
最后我想平均一些东西...... 所以让我们说如果一些提交在5h的时间跨度内首先从1变为2(我离开的代码,会让我达到这一点),那么让我们说它被重新分配到1然后它又回到了2新的时间跨度为6h,我希望能够得到两者并做到平均值,所以(5 + 6)/ 2。
由于
答案 0 :(得分:1)
我想我明白你要做什么。这有帮助吗
void Main()
{
var list = new List<SubmissionLog>
{
new SubmissionLog(1, 123, "1/24/2013 01:00:00", 1),
new SubmissionLog(2, 456, "1/24/2013 01:30:00", 1),
new SubmissionLog(3, 123, "1/25/2013 21:00:00", 2),
new SubmissionLog(4, 456, "1/25/2013 21:30:00", 2),
new SubmissionLog(5, 123, "2/25/2013 22:00:00", 1),
new SubmissionLog(6, 123, "2/26/2013 21:00:00", 2),
new SubmissionLog(7, 123, "2/16/2013 21:30:00", 1),
};
// split out status 1 and 2
var s1s = list.Where (l => l.StatusId == 1).OrderBy (l => l.Created);
var s2s = list.Where (l => l.StatusId == 2).OrderBy (l => l.Created);
// use a sub-query to get the first s2 after each s1
var q = s1s.Select (s1 => new
{
s1,
s2 = s2s.FirstOrDefault (s2 =>
s1.SubmissionId == s2.SubmissionId &&
s2.Created >= s1.Created
)
}
).Where (s => s.s1.PKId < s.s2.PKId && s.s2 != null);
// extract the info we need
// note that TotalSecond is ok in Linq to Object but you'll
// probably need to use SqlFunctions or equivalent if this is to
// run against a DB.
var q1 = q.Select (x => new
{
Start=x.s1.Created,
End=x.s2.Created,
SubmissionId=x.s1.SubmissionId,
Seconds=(x.s2.Created - x.s1.Created).TotalSeconds
}
);
// group by submissionId and average the time
var q2 = q1.GroupBy (x => x.SubmissionId).Select (x => new {
x.Key,
Count=x.Count (),
Start=x.Min (y => y.Start),
End=x.Max (y => y.End),
Average=x.Average (y => y.Seconds)});
}
public class SubmissionLog
{
public SubmissionLog(int id, int submissionId, string date, int statusId)
{
PKId = id;
SubmissionId = submissionId;
Created = DateTime.Parse(date, CultureInfo.CreateSpecificCulture("en-US"));
StatusId = statusId;
}
public int PKId {get;set;}
public int SubmissionId {get;set;}
public DateTime Created {get;set;}
public int StatusId {get;set;}
}