0

I am trying to group multiple items according to one column from my database table. I have combed through countless posts covering this topic and have had no luck in solving my issue.

This is the tutorial that I am following that does exactly what I need: http://ole.michelsen.dk/blog/grouping-data-with-linq-and-mvc/

This is what my Table Definition looks like:

|task_no(PK)|task_statement|field_name|

Here is an example of what I am trying to get:

field_name 1
  task_no | task_statement
  task_no | task_statement
  task_no | task_statement
field_name 2
  task_no | task_statement
  task_no | task_statement
field_name 3
  task_no | task_statement
  task_no | task_statement

Here are my models:

public partial class domain_names_tasks
{
    [Key]public int task_no { get; set; }
    public string task_statement { get; set; }
    public string field_name { get; set; }
}

class created from following tutorial.

    public class Group<T, K>
{
    public K Key;
    public IEnumerable<T> Values;
}

Here is my controller:

    public ActionResult DomainTaskStatements()
    {
        var taskStatements = context.domain_names_tasks.Select(ts => new domain_names_tasks
                                                            {
                                                                task_no = ts.task_no,
                                                                task_statement = ts.task_statement,
                                                                field_name = ts.field_name
                                                            }).ToList();

        var data = from ts in taskStatements
                   group ts by ts.field_name into tsg
                   select new Group<string, domain_names_tasks> { Key = tsg.Key, Values = tsg };
        return View(data.toList());
    }

I am getting two errors:

1st Error

Cannot implicitly convert type 'string' to 'GeologyWebApp.Models.domain_names_tasks'    

which is being caused here:

Key = tsg.Key

2nd Error

Cannot implicitly convert type 'System.Linq.IGrouping<string,GeologyWebApp.Models.domain_names_tasks>' to 'System.Collections.Generic.IEnumerable<string>'. An explicit conversion exists (are you missing a cast?)

being caused here:

Values = tsg

I am new to using LINQ and ASP.NET so I apologize for asking a question about an issue that may be simple to solve. I have had no luck looking though other questions related to LINQ grouping so I thought I would post this question. Thanks in advance!

Edit 1 -------

Sorry I did not notice my silly mistake with the Key and Value parameters in the Group class.

Here is my revised controller and view that now work.

Controller:

NOTE: I had to change my "taskStatements" query because I was getting the error: "The entity cannot be constructed in a LINQ to Entities query". I followed an answer found here to fix this issue.

    public ActionResult DomainTaskStatements()
    {
        var taskStatements = (from ts in context.Set<domain_names_tasks>()
                  select new
                  {
                      task_no = ts.task_no,
                      task_statement = ts.task_statement,
                      field_name = ts.field_name
                  }).ToList().Select(x => new domain_names_tasks { task_no = x.task_no, task_statement = x.task_statement, field_name = x.field_name });

        var data = from ts in taskStatements
                   group ts by ts.field_name into tsg
                   select new Group<string, domain_names_tasks> { Key = tsg.Key, Values = tsg };
        return View(data.ToList());
    }

View:

@model IEnumerable<GeologyWebApp.Models.Group<string, GeologyWebApp.Models.domain_names_tasks>>
@{
    ViewBag.Title = "DomainTaskStatements";
}

<table>
    <thead><tr><th>task no</th><th>task statement</th></tr></thead>
    <tbody>
        @foreach (var group in Model)
        {
            <tr><th colspan="2">@group.Key</th></tr>
            foreach (var task in group.Values)
            {
                <tr><td>@task.task_no</td><td>@task.task_statement</td></tr>
            }
        }
    </tbody>
</table>
Community
  • 1
  • 1
EighthEmperor
  • 19
  • 2
  • 8

1 Answers1

0
select new Group<string, domain_names_tasks> { Key = tsg.Key, Values = tsg };

should probably be

select new Group<domain_names_tasks, string> { Key = tsg.Key, Values = tsg };

because on

Group<T, K>

the key (K) is the second type parameter and the type (T) is the first.


However, I don't believe you need to have your own Group type, using 'group by' in LINQ should return:

IEnumerable<IGrouping<K,T>>

You could probably get away with this in the controller:

var data = from ts in taskStatements
           group ts by ts.field_name;

and then this in the view (for the nested loop):

foreach (var task in group)

instead of

foreach (var task in group.Values)
a little sheep
  • 1,416
  • 9
  • 6
  • Thank you for the reply! You are correct about the parameters for Group. I am sorry I made the silly mistake of overlooking that.. I am not sure about not using my own Group type. I tried what you suggested but am getting the following error in the nested for each loop: "foreach statement cannot operate on variables of type 'GeologyWebApp.Models.domain_names_tasks' because 'GeologyWebApp.Models.domain_names_tasks' does not contain a public definition of 'GetEnumerator'". Any ideas on this? – EighthEmperor Sep 15 '14 at 11:36
  • Hmm, what were you using for the model directive? I think it should be something like 'IEnumerable>'? (only with the namespaces, System.Linq.IGrouping/GeologyWebApp.Models or using directives for them) – a little sheep Sep 16 '14 at 22:50