LINQ Group By with multiple fields

Asked

Viewed 2,085 times

2

I am trying to return fields after a merge between collections, but am getting the following error:

foreach statement cannot Operate on variables of type 'Anonymoustype#1' because 'Anonymoustype#1' does not contain a public Definition for 'Getenumerator'

var lst = from p in Produto.produtos
        join c in Produto.categorias
        on p.IdCategoria equals c.IdCategoria
        group p by new { c.IdCategoria, c.Categoria }
            into g
            orderby g.Key.Categoria
            select new { ID = g.Key.IdCategoria, CategoriaNome = g.Key.Categoria, TotalItem = g.Count() };

foreach (var categ in lst)
{
    Console.WriteLine("ID: {0}, Categoria: {1}, Total Item: {2}", categ.ID, categ.CategoriaNome, categ.TotalItem);
    foreach (var item in categ)
    {
        Console.WriteLine("\t\tID: {0}, Produto: {1}", item.IdProduto, item.Produto); <b>// Linha com o Erro</b>
    }
}

2 answers

4

This returns List<n'>, in which n' is an anonymous guy:

var lst = from p in Produto.produtos
        join c in Produto.categorias
        on p.IdCategoria equals c.IdCategoria
        group p by new { c.IdCategoria, c.Categoria }
            into g
            orderby g.Key.Categoria
            select new { ID = g.Key.IdCategoria, CategoriaNome = g.Key.Categoria, TotalItem = g.Count() };

This iterates on List<n'>:

foreach (var categ in lst)
{ ... }

And this you try to iterate on n' which is not "eternal":

foreach (var item in categ)
{ ... }

Therefore, the mistake.


EDIT

According to your comment in the other answer, you want to group by categories. Therefore, modify your sentence to:

var lst = from p in Produto.produtos
    join c in Produto.categorias
    on p.IdCategoria equals c.IdCategoria
    group p by new { c.IdCategoria, c.Categoria }
        into g
        orderby g.Key.Categoria;

The first foreach gets like this:

foreach (var categ in lst)
{
    Console.WriteLine("ID: {0}, Categoria: {1}, Total Item: {2}", categ.Key.IdCategoria, categ.Key.Categoria, categ.Count());
    ...

The second one stays the same:

foreach (var item in categ)
{
    Console.WriteLine("\t\tID: {0}, Produto: {1}", item.IdProduto, item.Produto);
}
  • This code does not involve dynamic at all. The result of the first query is a List<n'>, in which n' is an anonymous guy.

  • 1

    Usually when I see questions about anonymous guys, I see the gang using dynamic. Thanks for the suggestion. I already amended.

  • 1

    Not at all :) Actually, the two things are very different. With anonymous types, we keep Static Typing, ie, we can only access properties/methods that actually exist. If we try an invalid access, the compiler will not let build, eg: var a = new { str = "uma string" }; a.propriedadeInvalida;

  • 1

    With dynamic, all accesses to this variable will be compiled dynamically when the program is run. That is, if there is an error in the code, we will only know when the exception is released. The code may have 15 errors, but will compile in the same.

0

Let’s change everything.

var lstCategorias = (from p in Produto.categorias select p).ToList();
foreach (var categoria in lstCategorias)
{
     var lstProdutos = (from p in Produto.produtos where p.IdCategoria=categoria.ID select p).ToList();
    Console.WriteLine("ID: {0}, Categoria: {1}, Total Item: {2}", categoria.ID, categoria.CategoriaNome, lstProdutos.Count);
    foreach (var item in lstProdutos)
    {
        Console.WriteLine("\t\tID: {0}, Produto: {1}", item.IdProduto, item.Produto); <b>// Linha com o Erro</b>
    }
}

Explaining:

Getting the categories

var lstCategorias = (from p in Produto.categorias select p).ToList();

Iterating with foreach

foreach (var categoria in lstCategorias)

Filtering category products within foreach

var lstProdutos = (from p in Produto.produtos where p.IdCategoria=categoria.ID select p).ToList();

Printing the result

Console.WriteLine("ID: {0}, Categoria: {1}, Total Item: {2}", categoria.ID, 
categoria.CategoriaNome, lstProdutos.Count);

New foreach to list the products of the category

foreach (var item in lstProdutos)
{
    Console.WriteLine("\t\tID: {0}, Produto: {1}", item.IdProduto, item.Produto); <b>// Linha com o Erro</b>
  • The ideal is for you to explain your answer, so we can understand better.

  • Gypsy, it didn’t work. It gives error with the same message only now in the second Foreach:<code> foreach (var item in categ) { Console.Writeline(" t tid: {0}, Product: {1}", item.Idproduct, item.Product); <b>// Line with Error</b> }</code>

  • @Kellysoares This is not my answer. In fact, I don’t know what your goal is. It would be nice to edit your answer and explain the goal so I can improve the answer.

  • I want to list the category groups in the first FOREACH and in the second I want to list the products that are part of this group.

  • It’s hard huh brothen...

  • I’m going to do another topic with an approximate structure.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.