我们有一个与他们的游泳者的数据库。 要创建一个排名,我们希望获得每个运动员的最快时间。

var rankings = (  
    from r in _db.Results  
        orderby r.swimtime  
        group r by r.athleteid into rg  
        select new  
        {
            AthleteId = rg.Key,  
            FirstName = rg.Min(f2 => f2.Athlete.firstname),  
            Swimtime = rg.Min(f8 => f8.swimtime),  
            hours = rg.Min(f9 => f9.swimtime.Hours),  
            minutes = rg.Min(f10 => ("00" + f10.swimtime.Minutes.ToString()).Substring(("00" + f10.swimtime.Minutes.ToString()).Length - 2)),    // to get 2 digits in minutes  
            seconds = rg.Min(f11 => ("00" + f11.swimtime.Seconds.ToString()).Substring(("00" + f11.swimtime.Seconds.ToString()).Length - 2)),    // to get 2 digits in seconds  
            milliseconds = rg.Min(f12 => (f12.swimtime.Milliseconds.ToString() + "00").Substring(0, 2)),    // because miliseconds are not always filled  
        }
    );
.

现在排名是正确创建的,但所示的时间不是。

我知道问题是什么,但不知道如何解决它:

在数据库中我们有一个有2次:00:01:02:10(1min2sec10)和00:00:56:95(56sec95)中的游泳者

结果我们得到的时间是分钟(= 00)的最小值,秒(= 02)的最小值,毫秒(= 10)的最小值 导致时间为00:00:02:10。

我们应该得到的是最快时间的小时,分钟,秒和毫秒(= 00:00:56:95)

任何关于如何解决这个问题的想法?

有帮助吗?

解决方案

This should do the trick:

from result in db.Results
group result by result.AthleteId into g
let bestResult = (
    from athleteResult in g
    orderby athleteResult.SwimTime
    select athleteResult).First()
orderby bestResult.SwimTime
select new
{
    AthleteId = bestResult.Athlete.Id,
    FirstName = bestResult.Athlete.FirstName,  
    BestTime = bestResult.SwimTime,  
}

The query fetches the best result from a group (all results from a single athelete), orders by that result, and uses that result to populate the final result.

其他提示

Stay away from calling .First on groups, as that can cause automatic requerying due to the difference between LINQ's group (key and elements) vs SQL's group (key and aggregates).

Instead, get the minSwimTime once and let it be.

var rankings =
  from r in _db.Results
  group r by r.athleteid into rg
  let minSwimTime = rg.Min(x => x.swimtime)
  select new
  {
    AthleteId = rg.Key,
    FirstName = rg.Min(f2 => f2.Athlete.firstname),
    Swimtime = minSwimTime,
    hours = minSwimTime.Hours,
    minutes = ("00" + minSwimTime.Minutes.ToString()).Substring(("00" + minSwimTime.Minutes.ToString()).Length - 2),    // to get 2 digits in minutes
    seconds = ("00" + minSwimTime.Seconds.ToString()).Substring(("00" + minSwimTime.Seconds.ToString()).Length - 2),    // to get 2 digits in seconds
    milliseconds = minSwimTime.Milliseconds.ToString() + "00").Substring(0, 2),    // because miliseconds are not always filled
  };

Also - don't do string formatting in the database. Database servers have better things to do than turn datetimes into text.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top