简体   繁体   中英

How do I to use Where, Group By, Select and OrderBy at same query linq?

I'm trying to make a linq using where, group by and select at same time but I cannot do it works and it always throws an exception.

How could I do it works ?

Linq

public ActionResult getParceiros(){
            //return all partners
            IList<ViewParceirosModel> lista = new List<ViewParceirosModel>();
            lista = context.usuarios.Where(u => u.perfil == RoleType.Parceiro)
                                    .Select(x => new ViewParceirosModel
                                    {
                                        id = x.id,
                                        nomeParceiro = x.nome,
                                        emailAcesso = x.email
                                    })
                                    .GroupBy(x => x.id)
                                    .OrderBy(x => x.nomeParceiro)
                                    .ToList();



            return View(lista);
        }

Exception

在此处输入图片说明

When you create a LINQ query with group by clause, you receive as result a grouped query. It is a kind of dictionary that has as key the field you chose to group and as value a list of records of this group.

So, you cannot order by "nomeParceiro" because this field is inside the group.

If you detail how you expect the result I can show you a code example for this.

You can find more details in this section of the doc: https://docs.microsoft.com/pt-br/dotnet/csharp/linq/group-query-results

You can use the following code.

IList<ViewParceirosModel> lista = new List<ViewParceirosModel>();

lista = context.usuarios.Where(u => u.perfil == RoleType.Parceiro)
            .Select(x => new ViewParceirosModel
            {
                id = x.id,
                nomeParceiro = x.nome,
                emailAcesso = x.email
            })
            .OrderBy(x => x.nomeParceiro)
            .GroupBy(x => x.id)
            .ToList();

or

 List<List<ViewParceirosModel>> listb = context.usuarios
            .Where(u => u.perfil == RoleType.Parceiro)
            .GroupBy(g => g.id).OrderBy(g => g.Key)
            .Select(g => g.OrderBy(x => x.nomeParceiro)).ToList();

Let's say ViewParceirosModel look like

public class ViewParceirosModel 
{
   public int id {get; set;}
   public List<string> nomeParceiro {get; set;}
   public List<string> emailAcesso {get; set;}
}

After that, you can Groupby then select combine with Orderby like below

IList<ViewParceirosModel> lista = new List<ViewParceirosModel>();

lista = context.usuarios.Where(u => u.perfil == RoleType.Parceiro)
        .Select(x => new ViewParceirosModel
        {
            id = x.id,
            nomeParceiro = x.nome,
            emailAcesso = x.email
        })
        .GroupBy(x => x.id)
        .Select(g => new ViewParceirosModel 
        { 
           id = g.Key, 
           nomeParceiro = g.Select(p => p.nomeParceiro).OrderBy(x => x.nomeParceiro).ToList()
           nomeParceiro = g.Select(p => p.emailAcesso).ToList()
         }) 
        .ToList();

Your program doesn't do what you want. Alas you forgot to tell you what you want, you only showed us what you didn't want. We'll have to guess.

So you have a sequence of Usarios.

IQueryable<Usario> usarios = ...

I don't need to know what a Usario is, all I need to know is that it has certain properties.

Your first step is throwing away some Usarios using Where : you only want to keep thos usarios that have a Perfil equal to RoleType.Parceirdo:

// keep only the Usarios with the Perfil equal to RoleType.Parceirdo:
var result = usarios.Where(usario => usario.Perfil == RoleType.Parceirdo)

in words: from the sequence of Usarios keep only those Usarios that have a Perfil equal to RoleTyoe.Parceirdo.

The result is a subset of Usarios, it is a sequence of Usarios.

From every Usario in this result, you want to Select some properties and put them into one ViewParceirosModel:

var result = usarios.Where(usario => usario.Perfil == RoleType.Parceirdo)
    .Select(usario => new ViewParceirosModel
    {
        Id = x.id,
        NomeParceiro = x.nome,
        EmailAcesso = x.email,
    })

In words: from every Usario that was kept after your Where, take the Id, the Nome and the Email to make one new ViewParceirosModel.

The result is a sequence of ViewParceirosModels. If you add ToList(), you can assign the result to your variable lists.

However your GroupBy spoils the fun

I don't know what you planned to do, but your GroupBy, changes your sequence of ViewParceirosModels into a sequence of "groups of ViewParceirosModels" Every ViewParceirosModel in one group has the same Id, the value of this Id is in the Key.

So if after the GroupBy you have a group of ViewParceirosModel with a Key == 1, then you know that every ViewParceirosModel in this group will have an Id equal to 1.

Similarly all ViewParceirosModel in the group with Key 17, will have an Id equal to 17.

I think Id is your primary key, so there will only be one element in each group. Group 1 will have the one and only ViewParceirosModel with Id == 1, and Group 17 will have the one and only ViewParceirosModel with Id == 17.

If Id is unique, then GroupBy is useless.

After the GroupBy you want to Order your sequence of ViewParceirosModels in ascending NomeParceiro.

Requirement

I have a sequence of Usarios. I only want to keep those Usarios with a Perfil value equal to RoleType.Parceirdo. From the remaining Usarios, I want to use the values of properties Id / Nome / Email to make ViewParceirosModels. The remaining sequence of ViewParceirosModels should be ordered by NomeParceiro, and the result should be put in a List.

List<ViewParceirosModel> viewParceiroModels = Usarios
    .Where(usario => usario.Perfil == RoleType.Parceirdo)
    .Select(usario => new ViewParceirosModel
    {
        Id = x.id,
        NomeParceiro = x.nome,
        EmailAcesso = x.email,
    }
    .OrderBy(viewParceirosModel => viewParceirosModel.NomeParceiro)
    .ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM