Behseini
Behseini

Reputation: 6320

Issue on Using Group by on Lambda and IEnumerable - ASP.Net

I need to render list of events (games) Grouped by the CreateDate

In controller I have

public ActionResult Index()
{
    var gs = db.Games.Include(p => p.Activity).GroupBy(e => e.CreateDate);
    return View(gs.ToList());
}

and in the view I have

@model IEnumerable<Game>
<h2>Games List:</h2>

<table>
    @foreach (Game e in Model)
    {
         <thead>
                <tr>
                    <td colspan="2">
                        <b>@e.CreateDate</b>
                    </td>
                </tr>
            </thead>
      }

        <tr>
            <td>
                <b>@e.GameStartTime - @e.GameEndTime</b>
            </td>

            <td>
                <b>@e.Activity.ActivityDescription</b>
            </td>
        </tr>
</table>

But I am getting this error

The model item passed into the dictionary is of type 'System.Collections.Generic.List1[System.Linq.IGrouping2[System.DateTime,MapApp.Models.Event.Event]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[MapApp.Models.Event.Event]'.

What am I doing wrong?

Upvotes: 0

Views: 81

Answers (2)

Shyju
Shyju

Reputation: 218702

The error is self explanatory. Your current code uses the GroupBy method and the result of that expression will be of type IQueryable<IGrouping<DateTime, Game>> and you are passing this to the view. But your view is strongly typed to a IEnumerable<Game>. This is the reason youare getting the type mismatch error.

You should create a view model for the grouped data and use that.

public class GroupedGame
{
  public DateTime CreatedDate { set;get;}
  public IEnumerable<Game> Games {set;get;}
}

Now in your action method,

var groupedData = db.Games.Include(p => p.Activity).GroupBy(e => e.CreateDate)
                    .Select(x=>new GroupedD { CreatedDate = x.Key, Games = x }).ToList();
return View(groupedData);

Now in your view which is strongly typed to a collection of our new view model

@model IEnumerable<GroupedGame>
<table>
@foreach(var group in Model)
{
  <tr>
     <td>@group.CreatedDate.ToString()</td>
     <td>
        @foreach(var g in group.Games)
        {
         <p>@g.Name</p>
        }
     </td>
  </tr>
}
</table>

Upvotes: 0

Matias Cicero
Matias Cicero

Reputation: 26281

The view is accepting a model of type IEnumerable<Game> which is a collection of games, basically, not gruped by anything.

You want to pass a grouped collection, so the correct type would be IEnumerable<IGrouping<DateTime, Game>>:

@model IEnumerable<IGrouping<DateTime, Game>>

Iterating over this will yield each group, i.e, IGrouping<DateTime, Game> instances. You can get each group key, by calling the Key property.

Iterating over IGrouping<DateTime, Game> will give you all the Game instances in that specific group.

Upvotes: 2

Related Questions