问题
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