1

我希望有人能够在这里指导我正确的方向......

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.
});

然后我要做的平均如下(同样,这将仅包括某些提交 id 提交日志的状态 1 和状态 2 的初始或第一次出现):

return revisedList.Count() > 0 ? revisedList.Select(a=> a.EndDateTime.Subtract(a.StartDateTime).TotalHours).Average() : 0;

所以,我希望有人能理解我的问题首先是什么......重新说明一下,我想获得每个状态1和2之间的时间跨度。我传递日期,然后我必须查找2这确保我会找到 1。如果我反过来寻找 1,那么 2 可能不存在(无论如何都不想要)。

最后我希望能够平均一些东西......所以让我们说如果一些提交首先在 5 小时的时间跨度内从 1 变为 2(我留下的代码将使我达到这一点),那么让我们假设它被重新分配给 1,然后在 6 小时的新时间跨度内又回到 2,我希望能够同时获得两者并取平均值,所以 (5+6)/2。

谢谢

4

1 回答 1

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;}
}
于 2013-02-08T10:39:38.087 回答