Group by Inside Group by Using EntityFramwork in Mvc5

大憨熊 提交于 2020-03-05 05:12:18

问题


Hi guys I am trying I try to bring the count for each male and female by age As in the table here

I was able to calculate all ages but I can not count the ages as boys and girls. I want help, please

here is my code in controller

public ActionResult AllCuont()
{

    var query = (from t in db.Pations
                 let range = (
                              t.Age>= 1 && t.Age < 5 ? "age from 1 to 4" :                                      
                              t.Age >= 5 && t.Age < 15 ? "age from 5 to 14" :
                              t.Age >= 15 && t.Age < 25 ? "age from 15 to 24" :
                              t.Age >= 25 && t.Age < 45 ? "age from 25 to 44" :
                              ""
                              )
                 group t by range into g


                 select new UserRange { AgeRange = g.Key,  Count = g.Count() }).ToList();
    //add the sum column.
    query.Add(new UserRange() { AgeRange = "Sum",Count = query.Sum(c => c.Count) });

    ViewBag.UserData = query;

    return View(db.Pations);
}

and my modal pation like this

   namespace app.Models
{
    public class Pation
    {
        [Key]
        public int Id { get; set; }

        public string PationName { get; set; }

        public int Age { get; set; }
        public Sex Sex { get; set; }

        public ApplicationUser User { get; set; }

    }
    public enum Sex
    {
        boys,
        girls,
    }
}

and this is modal for count my value

   public class UserRange
    {
        public string AgeRange { get; set; }
        public int Count { get; set; }

    }

how count for each male and female by age


回答1:


It's not clear to me what you want to put in the rows of your picture. The Pations? So one column could have more rows than another column? And what do you want to put in your last column?

Anyway, you have a sequence of of Pations (Patients?), and you want to divide them into groups of Pations with equal age range. Every group of same age range should be divided into group of Pations with equal Sex.

So let's first give every Pation and age range. For efficiency reasons, I'll number your age ranges from zero to four, later I'll change the age ranges into text

var query = dbContext.Pations                   // from the table of Pations
    .Where(patient => patient.Age < 45)         // keep only the Patiens younger than 45
    .Select(patient => new                      // from every remaining patient,
    {                                           // make one new object
         AgeRange = (patient.Age < 5) ? 0 :
                    (patient.Age < 15) ? 1 :
                    (patient.Age < 25) ? 2 : 3, // with a number 0..3, indicating the age range
         Gender = patient.Sex,                  // a property indicating the gender

         Patient = patient,                     // and the original Patient
    })

I continue the query by grouping all element into groups of Patients with equal age range. Because the age range is a number, this grouping is very efficient.

Every group consists of Patients within the same age range. I'll divide every group into a subgroup of Boys and a subgroup of Girls. The number of elements in every subgroup is counted.

    .GroupBy(patient => patient.AgeRange,       // group into groups of equal age range
    (ageRange, patientsWithThisAgeRange) => new // from the common ageRange and all
    {                                           // patients with this ageRange make one new
        AgeRange = ageRange,                   // remember the ageRange

        // put all Boys in this agegroup in a separate subgroup
        BoysGroup = patientsWithThisAgeRange                       
            .Where(patientWithThisAgeRange => patientWithThisAgeRange.Gender == Sex.Boys)
            .ToList(),

         // put all Girls in a separate sub group

        GirlsGroup = patientsWithThisAgeRange    // count number of girls in this group
            .Where(patientWithThisAgeRange => patientWithThisAgeRange.Gender == Sex.Girls)
            .ToList(),
    })

Because of the ToList, you'll have the Boys as well as the number of Boys. If you don't need the boys and the girls in your final result, but only the number of boys, replace ToList with Count

Finally, move all data from your database management system to your local process and convert the age group into text:

    .AsEnumerable()
    .Select(group => new
    {
        Description = AgeRangeToText(group.AgeRange),
        NrOfBoys = group.NrOfBoys,
        NrOfGirls = group.NrOfGirls,
    });

The only thing you'll have to do is to write a function that translates your ageRanges 0..4 into proper texts.



来源:https://stackoverflow.com/questions/53756697/group-by-inside-group-by-using-entityframwork-in-mvc5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!