i have 5 table from which i want to get some information using linq.i am using following query for reading data from data .
var query = (from GRD in _tblStudents.GetQueryable()
join apt in _tblApplicants.GetQueryable()
on GRD.ApplicantID equals apt.ApplicantID
join cls in _tblClasses.GetQueryable()
on GRD.CityID equals cls.ClassID
join prg in _tblPrograms.GetQueryable()
on cls.ProgramID equals prg.ProgramID
join city in _tblCities.GetQueryable()
on GRD.CityID equals city.CityID
where GRD.AcademicYearID == yearId && cls.ProgramID == programId
group apt by new{apt.Gender} into grouped
select new CityWiseStudentModel
{
CityName=city.CityName,
//'city' does not exist in the current context
Gender = grouped.Count(),
programName=prg.Program,
//'prg' does not exist in the current context
}
);
How i can get City name from city table and program name from prg table
group <--> by <--> into <--> is changed your scope to IGrouping<a,b>
My opinion is not only apt.Gender is your key but city.CityName and prg.Program
try this (or some similar):
group apt by new{apt.Gender, city, prg} into grouped
select new CityWiseStudentModel
{
CityName = grouped.Key.city.CityName,
Gender = grouped.Count(), //rename GenderCount
programName = grouped.Key.prg.Program,
// Gender = grouped.Key.Gender,
}
Remember that grouped will only hold the things you've grouped. If you only group adt, then city and prg will not be available in your select.
So you'll need to:
Include city and program into grouped (otherwise they're not available)
Access CityName and Program inside the grouped collection
Something like this should do the trick:
...
group new { apt, cls, prg, city } by new{apt.Gender} into grouped
select new CityWiseStudentModel
{
CityNames = grouped.Select(g => g.city.CityName),
...
programNames = grouped.Select(g => g.prg.Program)
}
Related
I have two tables, Organization and ApplicationUser. The relationship between them is One to Many. That means one Organization can have multiple Users. Now I need to write a query to show some organization properties along with the total users for each organization. I am trying to write the query. But after GroupBy function whenever I try to fetch the Property nothing comes. Here is the query:
var lists = await (from org in _dbContext.Organizations.AsNoTracking()
join dept in _dbContext.Departments.AsNoTracking() on org.Id equals dept.OrganizationId into orgDeptTemp
from orgDept in orgDeptTemp.DefaultIfEmpty()
join user in _dbContext.ApplicationUsers.AsNoTracking() on org.Id equals user.OrganizationId into orgUserTemp
from orgUser in orgUserTemp.DefaultIfEmpty()
group org by org.Id into orgGroupTemp
select new OrganizationDto
{
OrganizationId = orgGroupTemp.Key,
OrganizationName = orgGroupTemp.Key.......,
TotalUsers = How to get the total user
})
.ToListAsync();
In SQL the only available columns after a GROUP BY are the group key and aggregated columns.
You need to add them into the group by line. So for example, group by org id and name
assuming your model is set up correctly use navigation properties
var query = from org in _dbContext.Organizations
where org.Departments.Any(d => d.Whatever)
select new OrganizationDto
{
OrganizationId = org.Id,
OrganizationName = org.Name,
TotalUsers = org.Users.Count(),
};
var list = await query.AsNoTracking().ToListAsync();
I want to fetch the list of employer with inner list details to show multiple address. I have tried the following code and can able to fetch the EmpConnectionNumber, EmpState. I could able to fetch the StoreID, StoreStaffName, Address, ContactNumber details from store and StoreStaffList tables.
List<Model.ListEmployer.Employer> employer_list = null;
employer_List = (from a in Employer
join b in store on a.EmployerID equals b.EmployerID
join c in StoreAddress on b.StoreID equals c.StoreID
join d in StoreStaffList on c.storeAddressID equals d.StoreAddressID
where a.EmployerType == "Contract"
group new { a, c } by new { a.ConnectionNumber, c.state }
into grp
select new Model.ListEmployer.Employer
{
EmpConnectionNumber = grp.Key.ConnectionNumber,
EmpState = grp.Key.State,
AddressHistory = new List<Model.list Employer.AddressHistory>
{
new Model.ListEmployer.AddressHistory
{
StoreID = b.StoreID,
StoreStaffName = d.StoreStaffName,
Address = d.Address,
ContactNumber = d.ContactNumber
}
}
}). ToList();
Can anyone help on this solution to get it done.
my intension is to show multiple address details inside the same Employer list itself
i have got 3 tables on MySql database. i want to do left join between this 3 tables and count with group by.
City Table
Id
Name
School Table
Id
CityId
Name
Student Table
Id
SchoolId
Name
/* MySql raw query like this: */
select Count(tstudent.id) as StudentCount, tcity.Id, tcity.Name
from City tcity
left join School tschool on tcity.Id = tschool.CityId
left join Student tstudent on tschool.Id = tstudent.SchoolId
group by tcity.Id;
With EF Core i try like this:
class CityWithStudentCount {
public int Id { get;set; }
public string CityName { get;set; }
public int StudentCount { get;set; }
}
Ef Core :
var db = new MyDbContext();
var result = (from city in db.City
join school in db.School on city.Id equals school.CityId into tcity
from r1 in tcity.DefaultIfEmpty()
join student in db.Student on school.Id equals student.SchoolId into tschool
from r2 in tschool.DefaultIfEmpty()
select new CityWithStudentCount
{
Id = city.Id,
CityName = city.Name,
StudentCount = tschool.count()
} into s1
group s1 by s1.Id)
.Select(s=>s.ToList())
.ToList();
Result must be like that :
1 City1 10
2 City2 3
3 City3 0
4 City4 0
5 City5 12
How can i do like this query for this result with Entity Framework Core. Thank you.
Your query is wrong.
var result = (from city in db.City
join school in db.School on city.Id equals school.CityId into t1
from school in t1.DefaultIfEmpty()
join student in db.Student on school.Id equals student.SchoolId into t2
from student in t2.DefaultIfEmpty()
group student by new { city.Id,city.Name } into cityGrouped
select new CityWithStudentCount
{
Id = cityGrouped.Key.Id,
CityName = cityGrouped.Key.Name,
StudentCount = cityGrouped.Count(x => x.student != null)
}
.ToList();
Also, I strongly suggest you to use navigation properties instead of manual building joins.
Let'say there's a basic SQL db with the following structure:
Customers table
Customer ID
Name
PostCode
Email
Orders table
Order ID
Customer ID
Description
Items table
Item ID
Order ID
Name
Cost
So a customer can have many orders and an order can have many items.
What's the most appropriate LINQ query to run in order to achieve the following result where the Order Item Names result is a comma separated string:
Customer Name | Customer Email | Order Item Names
So effectively the Orders table is acting like a link table between the Customer and Order Items tables. I then want to concatenate the names of all items which are associated with all orders into a single string and return it in the same result as the customer details.
I've got the following working as expected which will return a result for each order item:
IQueryable<CustomerSearchResult> customerSearchResult = from customer in db.Customers
join order in db.Orders on customers.CustomerId equals order.CustomerId
join item in db.OrderItems on order.OrderId equals item.OrderId
where customerId.Equals(userId)
select new CustomerSearchResult {
customerName = customer.Name,
customerEmail = customer.Email,
itemName = item.Name
};
EDIT 21st March 2014
There are some cases when there will be no associated OrderItems in which case the CustomerSearchResult should still be returned but with the ItemNames property empty.
After you have results
var query = from c in db.Customers
join o in db.Orders on c.CustomerId equals o.CustomerId
join i in db.OrderItems on o.OrderId equals i.OrderId
where c.CustomerId == userId
select new {
CustomerName = c.Name,
CustomerEmail = c.Email,
ItemName = i.Name
};
Group them and concatenate item names:
var result = from r in query.AsEnumerable()
group r by new { r.CustomerName, r.CustomerEmail } into g
select new CustomerSearchResult {
CustomerName = g.Key.CustomerName,
CustomerEmail = g.Key.CustomerEmail,
ItemNames = String.Join(",", g.Select(r => r.ItemName))
};
You should do names concatenation in-memory, because EF will not be able to translate it into SQL.
So I am selecting from a person table and I need to select the group ids of the groups that the person is in. How can I do this.
So far, I have:
var p = (from p in Context.Person
join g in Context.Group
on p.PersonId equals g.PersonId
select new
{
Name = p.Name,
Age = p.Age,
groupIds = ?????
}
So in the group table it will be a primary key of GroupId and PersonId so I need to select all the group ids. How can this be done?
You want a GroupJoin rather than a Join. The difference is that rather than having all of the related items flattened into a list of pairs, it groups all of the joined items into a sequence:
var query = from p in Context.Person
join g in Context.Group
on p.PersonId equals g.PersonId into groups
select new
{
Name = p.Name,
Age = p.Age,
groupIds = groups.Select(g => g.GroupId),
};
Using query syntax the use of the into keyword in conjunction with a join will result in a GroupJoin instead of a Join.
I coded on SO's editor. If I understand right you want Person's groups.
Otherwise correct me please.
var p = from p in Context.Person
select new
{
Name = p.Name,
Age = p.Age,
groups = from g in Context.Group
where p.PersonId == g.PersonId
select g.GroupId
};