Get common lists in Linq - c#

I have list of StuedntInfo table
and i have List of Classes
var classesList = GetClasses2nd(2017);
Reasult is
ClassId = 5
ClassId = 4
ClassId = 8
Now is it possible to get list of StudentInfo records dynamically where classes id are present in StudentInfo table?
Also if possible to get list of Location objects as well?

I've had to make a few assumptions about your model / db context, but something like this should work:
var classesList = GetClasses2nd(2017);
//get the class Ids
var classIds = classesList.Select(x => x.ClassId);
var students = db.Students
.Include(x=>x.Location) //assuming you have this navigation property on your model
.Where(x=> classIds.Contains(x.ClassID))
.ToList();
Note: The Include will only work if you have a navigation property set on your model.
https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx

try Code:
var classidList= ( From p in db.student
group p by p.studentid into jj
select new {
classid=jj.max(c=>c.classid)
}).ToList();

Related

LINQ aggregate multiple tables

I have the following database. A list of companies. Each company has multiple employees and multiple contractors.
dbo.Companies (CompanyId, Name)
dbo.Employees (Id, CompanyId, Name ...)
dbo.Contractors(Id, CompanyId, Name...)
I want to get output like so
CompanyName #Employees #Contractors
abc 0 10
xyz 25 999
I am trying to avoid doing 2 queries, one to get contractors and one to get employees and then merging them. Is there a way to get it done in one go?
n.b. i have
class CompanySummary{
string Name {get; set;}
int EmpCount {get; set;}
int ConCount {get; set;}
}
so I can use a collection of this type as result
If you have defined navigation properties (and if you haven't, may be it's a good time to do that), the query should be quite simple:
var query = from c in db.Companies
select new CompanySummary
{
Name = c.Name,
EmpCount = c.Employees.Count(),
ConCount = c.Contractors.Count(),
};
Of course you can do that manually, but the above is the preferred way with EF:
var query = from c in db.Companies
select new CompanySummary
{
Name = c.Name,
EmpCount = db.Employees.Count(e => e.CompanyId == c.Id),
ConCount = db.Contractors.Count(cc => cc.CompanyId == c.Id),
};
In both cases you'll get a single SQL query.
If you are using Entity Framework to communicate with the database and have the tables linked with foreign keys you can probably do it in one query. It would look something like this:
IEnumerable<CompanySummary> companySummary = null;
using (CompanyEntities dbContext = new CompanyEntities())
{
companySummary = dbContext.Companies
.Include(company => company.Employees)
.Include(company => company.Contractors)
.Select(company => new CompanySummary
{
Name = company.Name,
EmpCount = company.Employees.Count(),
ConCount = company.Contractors.Count()
});
}

Data in Linq query not in join is not in output to json only those that are related in 2 classes are showing up

The basis of this question is from this question:
Combine 2 classes with adding data and 1 table has a colllection list of the other table and wanting to use linq to display
In which I "thought" the problem was solved.
However as I added in a new object to the List, now this join query does not output it
reportData.Add(new ReportData() {ReportGroupId = 3, ReportGroupName = "Straggler", SortOrder = 3, Type = 1});
var reports = reportDefinition.GroupBy(r=>r.ReportGroupId);
var query = reportData.Join(reports, d => d.ReportGroupId, gr => gr.Key,
(r,gr) => new
{
r.ReportGroupName,
items = gr.ToList(),
r.ReportGroupId
});
Here is the dotNetFiddle https://dotnetfiddle.net/IIBFKG
Why doesn't the item that I added to the ReportData not show up? Is it the type of JOIN in Linq?
I think the linked question was not answered correctly.
Looks like all you need is a simple Group Join:
var query =
from d in reportData
join r in reportDefinition on d.ReportGroupId equals r.ReportGroupId into items
select new
{
d.ReportGroupName,
items = items.ToList(),
d.ReportGroupId
};

Entity Framework Include without query

Can I include a related object without a query?
With query:
Item item = _db.Items
.Include(i=>i.Supplier)
.Where(....)
Without query:
var item = new Item { Name = "Test", SupplierId = 1 };
item.Include(i => i.Supplier); //something like that...
I don't really understand your question...
First of all Where return multiple objects
IQueryable<Item> items = _db.Items
.Include(i=>i.Supplier)
.Where(....)
Then the result is an IQueryable, the items and suppliers objects are not materialized for the moment. You have to use ToList() for example to enable materialization and query the database.
For the Include method, it's just a join to query Items and Suppliers relationship.
But the Include extension method is only available in IQueryable and not for the entity.
Supplier is normal a simple navigation property on item entity
class Item
{
public virtual Supplier Supplier {get; set;}
}
so you can access using
var item = new Item { Name = "Test", SupplierId = 1 };
item.Supplier = ....
if you want establish a relation with you have to get the supplier
item.Supplier = _db.Suppliers.First(s => s.SupplierId = 1);

Creating a list of objects belonging to another class using linq

I have a Films class, that has a property of a list of screenings. I'm using two listboxes, one for the Films then one for the showings. I'm trying to read the films and the screenings in from a database, the relationship being that the FilmID is the foreign key in the screenings. I was wondering if it was possible to query the database so i'd create several Films objects with the screenings being added to the list of screenings in the films class. So the screenings that I have that have a FilmID of 3 for example will all go in the list of screenings in the films class that has the ID of 3 also
I've tried this, but i'm unsure as to where to go next. Any help would be greatly appreciated
var query = from f in db.Films
join s in db.Showing__s
on f.FilmID equals s.FilmID
select new
{
fID = f.FilmID
FilmName = f.FilmName,
FilmDetails = f.FilmDetails,
ReleaseDate = f.Release_Date,
Rating = f.AgeRating,
ShowDate = s.ShowDate,
FilmID = s.FilmID
};
If your relationships are properly set up, you should just use the navigation properties.
But if you have to do it in a different way, you could try something like this:
from f in db.Films
select new
{
film = f,
screenings = from s in db.Screenings
where s.FilmId == f.FilmId
select s
};

Get list of child records

I have a database that looks like this:
tbl_Seminar
ID
isActive
tbl_SeminarFees
ID
seminar_id -- foreign key
fee_text
I want to get all seminars that are active (isActive ==1) and a list of the fees associated with that seminar. Each Seminar may have n records in tbl_SeminarFees that are its fees. I am able to return a linq structure that returns me a list of objects that look like this {seminar, SeminarFee} but I wanted to create a nested structure that looks like this:
{seminar, List<SeminarFee>}
What should my linq query look like?
here is my linq currently:
var results = from s in context.Seminar
join p in context.SeminarFees on
s.ID equals p.SeminarID
where s.IsActive == 1
select new
{
Seminar = s,
Fees = p
};
How do I change this to get a list of these: {seminar, List<SeminarFee>}
Thanks
UPDATE
#lazyberezovsky gave me a good idea to use a group join and into another variable. But then how do I loop through the result set. Here is what I have now:
foreach (var seminarAndItsFeesObject in results)
{
//do something with the seminar object
//do something with the list of fees
}
This however gives me the following error:
Argument type 'SeminarFees' does not match the
corresponding member type
'System.Collections.Generic.IEnumerable`1[SeminarFees]'
What am I doing wrong?
Thanks
You can use group join which groups inner sequence items based on keys equality (a.k.a. join..into) to get all fees related to seminar:
var results = from s in context.Seminar
join f in context.SeminarFees on
s.ID equals f.SeminarID into fees // here
where s.IsActive == 1
select new
{
Seminar = s,
Fees = fees
};
You can't call ToList() on server side. But you can map results on client later.
BTW You can define navigation property Fees on Seminar object:
public virtual ICollection<SeminarFee> Fees { get; set; }
In this case you will be able load seminars with fees:
var results = context.Seminar.Include(s => s.Fees) // eager loading
.Where(s => s.IsActive == 1);
var results = from s in context.Seminar
join p in context.SeminarFees on s.ID equals p.SeminarID
where s.IsActive == 1
group p by s into grouped
select new {
Seminar = grouped.Key,
Fees = grouped.ToList()
};

Categories