LINQ группировка и упорядочивание верхних 5 строк в список ViewModel

1

Я пытаюсь создать новый список лучших пяти лидеров хитов для своего веб-приложения софтбола. Я новичок в MVC, и мне не удается скомпоновать этот запрос и передать информацию в мою ViewModel. Я хотел бы использовать вызов без запроса, например, "результаты var" в контроллере, если это возможно. Я пытаюсь сгруппировать AtBats с помощью PlayerID в таблице Stat. Я также хотел бы иметь возможность вызвать FirstName и LastName игрока из таблицы Player в моем представлении для этого списка. Спасибо за помощь!

В Stat.cs

using System;

namespace TheFlyingPig.Models
{
    public class Stat
    {
        public int StatID { get; set; }
        public int SeasonID { get; set; }
        public int PlayerID { get; set; }
        public DateTime GameDate { get; set; }
        public int AtBats { get; set; }
        public int Hits { get; set; }
        public int Walks { get; set; }
        public int Singles { get; set; }
        public int Doubles { get; set; }
        public int Triples { get; set; }
        public int HomeRuns { get; set; }
        public int RBIs { get; set; }
        public int Runs { get; set; }
        public int ReachedOnErrors { get; set; }
        public int SacrificeFlies { get; set; }

        public virtual Season Season { get; set; }
        public virtual Player Player { get; set; }
    }
}

В Player.cs

using System;
using System.Collections.Generic;

namespace TheFlyingPig.Models
{
    public class Player
    { 
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public virtual ICollection<Stat> Stats { get; set; }
    }
}

В Season.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace TheFlyingPig.Models
{
    public class Season
    {
        public int SeasonID { get; set; }
        public string SeasonName { get; set; }

        public virtual ICollection<Stat> Stats { get; set; }
    }
}

В TeamStat.cs(My ViewModel я пытаюсь подтолкнуть эти данные)

//Get the season leaders from controller
public List<Stat> SeasonLeadersHits { get; set; }

Я попробовал оба из следующих параметров в моем контроллере (HomeController.cs), но я просто не могу пробиться сюда, чтобы получить лидеров Top 5 Hits для команды.

var lastSeasonId = db.Seasons.OrderByDescending(u => u.SeasonID).Select(u => u.SeasonID).FirstOrDefault();

var leadersAtBats = (from s in db.Stats
                     join p in db.Players on s.PlayerID equals p.ID
                     where s.SeasonID == lastSeasonId
                     group s.Hits by s.PlayerID into g
                     order by s.Hits descending
                     select new { LeaderID = g.Key, LeaderList = g.ToList() })
                     .Take(5);

var results = db.Stats.Where(s => s.SeasonID == lastSeasonId).GroupBy(s => s.PlayerID, s => s.Hits, (key, g) => new { PlayerId = key, Hits = g.ToList() });

var view = new TeamStat() { SeasonLeadersHits = results };
return View(view);
  • 0
    В чем проблема?
  • 0
    Ошибка говорит, что не может неявно преобразовать тип 'System.Linq.IQueryable <AnonymousType # 1>' в 'System.Collections.Generic.List <TheFlyingPig.Models.Stat>'. Существует явное преобразование (вам не хватает приведения?)
Показать ещё 2 комментария
Теги:
linq
asp.net-mvc-5
visual-studio-2013

1 ответ

0
Лучший ответ

В чем причина "GroupBy"? Мне кажется, что все, что вам нужно сделать, это выбрать верхние 5 строк из db.Stats ordering по Hits downcending. Как это:

var results = (
    from s in db.Stats
    join p in db.Players on s.PlayerID equals p.ID
    where s.SeasonID == lastSeasonId
    order by s.Hits descending
    select new { Player = p, Stats = s })
    .Take(5).ToList();

** Я предполагаю, что каждая строка в Stats представляет собой год.

Редактировать:

Итак, каждый объект Stat представляет собой одиночную игру (пропустил это в первый раз). Если вы хотите Stat насчитывал год, то часть, которая отсутствует в запросе является Sum() из хитов (и, вероятно, других статистических данных, а). Этот запрос даст вам 5 лучших сезонов, которые будут оцениваться по количеству просмотров, а также сезону и игроку, связанным с ним.

var hitLeaders = (from s in stats
                  join p in players on s.PlayerID equals p.ID
                  group s by new { s.PlayerID, s.SeasonID } into g
                  select new 
                  { 
                     PlayerID = g.Key.PlayerID, 
                     SeasonID = g.Key.SeasonID, 
                     Hits = g.Sum(sum => sum.Hits),
                     AtBats = g.Sum(sum => sum.AtBats),
                     Walks = g.Sum(sum => sum.Walks),
                     Singles = g.Sum(sum => sum.Singles),
                     Doubles = g.Sum(sum => sum.Doubles),
                     Triples = g.Sum(sum => sum.Triples),
                     HomeRuns = g.Sum(sum => sum.HomeRuns),
                     RBIs = g.Sum(sum => sum.RBIs),
                     Runs = g.Sum(sum => sum.Runs),
                     ReachedOnErrors = g.Sum(sum => sum.ReachedOnErrors),
                     SacrificeFlies = g.Sum(sum => sum.SacrificeFlies)
                  }).OrderByDescending(s => s.Hits).Take(5);

Теперь вторая проблема, которую вы собираетесь решить, заключается в том, что вы не можете присвоить результат этого запроса вашей модели представления, поскольку она создает IEnumerable<of AnonymousType> но модель представления ожидает List<Stat>. Я бы предложил создать объект, который представляет собой статистику за год для игрока; что-то вроде этого:

public class TotalStat
{
    public int TotalStatID { get; set; }
    public int SeasonID { get; set; }
    public int PlayerID { get; set; }
    public int AtBats { get; set; }
    public int Hits { get; set; }
    public int Walks { get; set; }
    public int Singles { get; set; }
    public int Doubles { get; set; }
    public int Triples { get; set; }
    public int HomeRuns { get; set; }
    public int RBIs { get; set; }
    public int Runs { get; set; }
    public int ReachedOnErrors { get; set; }
    public int SacrificeFlies { get; set; }
}

Затем вам просто нужно изменить модель представления на:

public List<TotalStat> SeasonLeadersHits { get; set; }

И измените запрос на создание IEnumerable<TotalStat>. Вы достигнете этого, изменив new {} на new TotalStat {}, например:

//...
group s by new { s.PlayerID, s.SeasonID } into g
select new TotalStat
{ 
    PlayerID = g.Key.PlayerID, 
//...
  • 0
    Мне нужен GroupBy, потому что у каждого игрока может быть несколько StatID в течение сезона. Мне нужно общее количество за сезон для каждого ID игрока, а затем упорядочить по убыванию.
  • 0
    Работает как шарм, но мне пришлось изменить публичный список <TotalStat> SeasonLeadersHits {get; set;} для открытого IEnumerable <TotalStat> SeasonLeadersHits {get; установлен; } чтобы это работало. Спасибо вам большое!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню