使用Entity进行子集合的最佳订购方式

时间:2015-12-31 11:57:27

标签: range entity parent-child

我正在寻找这个简单问题的最佳解决方案 在C#/ Entity中运行以下SQL:

select user.name, userstat.point from user, userstat where userstat.user_id = user.id order by userstat.point desc

有一个用户表[Id,Name,...]和统计表[Id,UserId,Point。 ...],它通过Statistic.UserId连接到User。这是一个1:1的关系,因此每条用户记录都有(最多)1条统计记录。

我希望有一个列表User + Point,由Point desc命令,并选择一个范围,比方说1000-1100。

目前我有这个:

public List<PointItem> Get(int startPos, int count)
{
using (DB.Database db = new DB.Database())
{
   var dbList = db.Users.Where(user => .... ).ToList();

   List<PointItem> temp = new List<PointItem>(count);
   foreach (DB.User user in db.Users)
   {
       //should be always 1 stat for the user, but just to be sure check it...
       if (user.Stats != null && user.Stats.Count > 0)
          temp.Add(new PointItem { Name = user.Name, Point = user.Stats.First().Point });
   } <--- this foreach takes forever

   return temp.OrderByDescending(item => item.Point).Skip(startPos).Take(count).ToList();
}

}

它工作正常,但是当我有10000个User(10000 UserStat)时,它运行100秒,这比我想要的慢1000倍。

有比这更有效的解决方案吗?

如果我运行SQL,基本上10K记录需要0秒。

修改

我做得更快,现在100秒 - &gt; 1秒,但我仍然希望它更快(如果可能的话)。

var userPoint = db.Users
    .Where(u => u.UserStats.Count > 0 && ....)  
    .Select(up => new
    {
        User = up,
        Point = up.UserStats.FirstOrDefault().Point
    })
    .OrderByDescending(up => up.Point)
    .ToList();

var region = userPoint.Skip(0).Take(100);

1 个答案:

答案 0 :(得分:0)

好的,我找到了解决方案,下面的代码是0.05秒。只需要从孩子到父母:

    using (DB.Database db = new DB.Database())
    {
        var userPoint = db.UserStats
            .Where(s => s.User.xxx .....)
            .Select(userpoint => new
            {
                User = userpoint.User.Name,
                Point = userpoint.Point
            })
            .OrderByDescending(userpoint => userpoint.Point)
            .ToList().Skip(startPos).Take(count);
    }