Left join with group by linq lambda expression c#? - c#

I want to write left join using linq lambda expression. I have tried query using join but now I want to create using left join so any one can help me how can do.
Here this is my query:
var UserList = db.UserInfo
.Join(db.Course, u => u.id, c => c.userid, (u, c) =>
new { u, c }).GroupBy(r => r.u.id)
.Select(g => g.OrderByDescending(r => r.c.datetime)
.FirstOrDefault()).OrderByDescending(a => a.u.datetime).ToList();
Using this query, I don't want user data those who are not in course table, so I want to this data also in course table in userid in or not.

you can use
var qry = Foo.GroupJoin(
Bar,
foo => foo.Foo_Id,
bar => bar.Foo_Id,
(x,y) => new { Foo = x, Bars = y })
.SelectMany(
x => x.Bars.DefaultIfEmpty(),
(x,y) => new { Foo=x.Foo, Bar=y});
ref: How do you perform a left outer join using linq extension methods

Related

Convert Join to GROUP JOIN while using Lambda expression in linq c#

I am trying to change a join to LEFT outer join but getting all sorts of conversion errors. Below is my current join, can anybody provide any suggestion on how to do this without changing the actual logic of this join?
BRAND_NAME_MAP_MASTER objBrandNameMap = DB.PFC_MAP_MASTERs.Join(
DB.BRAND_NAME_MAPs,
a => a.BRAND_NAME_MAP_ID, b => b.BRAND_NAME_MAP_ID,
(a, b) => new { a, b }).Where(x => x.a.BRAND_NAME_MAP_ID == BrandNameMapID &&
x.b.BRAND_NAME_MAP_ID == BrandNameMapID).Select(x => x.a).FirstOrDefault();
Since you are only keeping a in the end changing to a left join implies not caring whether b matches or not, so the result is just:
BRAND_NAME_MAP_MASTER objBrandNameMap = DB.PFC_MAP_MASTERs
.Where(a => a.BRAND_NAME_MAP_ID == BrandNameMapID)
.FirstOrDefault();
You should use NetMage's answer if thats your entire query. But, if you still need to do a left outer join then use this:
BRAND_NAME_MAP_MASTER objBrandNameMap = DB.PFC_MAP_MASTERs.GroupJoin(
DB.BRAND_NAME_MAPs,
a => a.BRAND_NAME_MAP_ID,
b => b.BRAND_NAME_MAP_ID,
(a, b) => new { a, b })
.SelectMany(
x => x.b.DefaultIfEmpty(),
(x,y) => new { x.a, y})
.Where(x => x.a.BRAND_NAME_MAP_ID == BrandNameMapID)
.Select(x => x.a).FirstOrDefault();
Your intent doesn't make sense since you are only fetching a. If you only want a then there is no need of left join. Though i have written the query which will give you left join result. You can use it the way you want.
BRAND_NAME_MAP_MASTER objBrandNameMap =
(from Master in DB.PFC_MAP_MASTERs.Where(x=>x.BRAND_NAME_MAP_ID ==BrandNameMapID)
join Map in DB.BRAND_NAME_MAPs.Where(z=>z.BRAND_NAME_MAP_ID ==BrandNameMapID)
on Master.BRAND_NAME_MAP_ID equals Map.BRAND_NAME_MAP_ID
into result
from res in result.DefaultIfEmpty()
select new {Master,res}).ToLisT()
Hope it helps.

Convert SQL to Linq queries in Entity Framework

How do I convert this query to a LINQ query in Entity Framework? I am a new programmer still in school
SELECT
studfirstname, studlastname, grade
FROM
students
INNER JOIN
Student_Schedules ON students.StudentID = Student_Schedules.StudentID
INNER JOIN
Classes ON Student_Schedules.ClassID = Classes.ClassID
INNER JOIN
Subjects ON Classes.SubjectID = Subjects.SubjectID
WHERE
SubjectName = 'Introduction to Art';
As you are new in Lambda and LINQ I tried in the following Lambda to be as descriptive as possible..... You can use the Long Aliases in short form also
student_schedules as ss OR studentsANDstudent_schedules as s_s_sch... Try this ...Hope this helps.... #Abdul Hameed
var filteredData = context.Students // your starting point
.Join(context.Student_Schedules, // the source table of the inner join
students => students.StudentID, // Select the primary key (the first part of the "on" clause in an sql "join" statement)
student_schedules => student_schedules.StudentID),// the foreign key
(students, student_schedules) => new { students, student_schedules })
.Join(context.Classes,
classes => classes.ClassID,
studentsANDstudent_schedules => studentsANDstudent_schedules.student_schedules.ClassID),
(classes, studentsANDstudent_schedules) => new { classes, studentsANDstudent_schedules })
.Join(context.Subjects,
subjects => subjects.SubjectID,
studentsANDstudent_schedulesANDClasses => studentsANDstudent_schedulesANDClasses.classes.SubjectID),
(subjects, studentsANDstudent_schedulesANDClasses) => new { subjects, studentsANDstudent_schedulesANDClasses })
.Where(allMergedTables => allMergedTables.subjects.SubjectName == "Intoduction to Art").ToList();
And this is the shortened version of the above one...
var filteredData = context.Students
.Join(context.Student_Schedules, s => s.StudentID, sch => sch.StudentID),
(s, sch) => new { s, sch })
.Join(context.Classes, c => c.ClassID, s_sch => s_sch.sch.ClassID),
(c, s_sch) => new { c, s_sch })
.Join(context.Subjects, sj => sj.SubjectID, s_sch_c => s_sch_c.c.SubjectID),
(sj, s_sch_c) => new { sj, s_sch_c })
.Where(all => all.sj.SubjectName == "Intoduction to Art")
.ToList();
You can use LINQ syntax:
from student in context.Students
join schedule in context.Student_Schedules on student.StudentID equals schedule.StudentID
join #class in context.Classes on schedule.ClassID equals #class.ClassID
join subject in context.Subjects on #class.SubjectID equals subject.SubjectID
where subject.SubjectName == "Introduction to Art"
var students = context.Students.Include("Student_Schedules")
.Include("Classes")
.Include("Subjects").Where(s => s.Subjects.Contains("Intoduction to Art"));
Info -> https://msdn.microsoft.com/en-us/data/jj574232.aspx

Linq to DataSet

I want to pick up all Sellers that aren't boss of a department.
How can I make this? In this query below, only the Sellers that are bosses of a department are picked up, I want the opposite of thereof.
My query:
var query = db.Sellers
.Join(db.Departments,
s => s.Id,
d => d.BossId,
(s, d) => new { Seller = s, Department = d })
.Where(a => a.Seller.Id == a.Department.BossId) ????
.Select(x => x.Seller).ToList();
In the "Where" part, I tried a => a.Seller.Id != a.Department.BossId, but it's wrong I have 3 sellers that aren't bosses.
I tried with this way too:
var listNonBoss = (from s in db.Sellers
join d in db.Departments on s.Id equals d.BossId
select s.Id).ToList();
I want just the opposite of these queries.
Sometimes it's easier to break it into multiple steps.
First, get the collection of all boss IDs:
var bossIDs = db.Departments.Select(x => x.BossId);
Then get all sellers whose IDs are not in that collection:
var listNonBoss = db.Sellers.Where(x => !bossIDs.Contains(x.Id)).ToList();
Join in your code will do an inner join, meaning it'll filter out sellers who don't have a boss.
To do the opposite you can do an outer join, and then remove the ones who have a boss. In fluent LINQ an outer join is done by doing a GroupJoin and then SelectMany.
Something like this:
var query = db.Sellers
.GroupJoin(db.Departments, s => s.Id, d => d.BossId, (s, d) => new { Seller = s, Department = d })
.SelectMany(x => x.d.DefaultIfEmpty(), (seller, department) => new { s.seller, department})
.Where(a => a.department.BossId == null)
.Select(x => x.Seller).ToList();
Or, using query syntax:
var listNonBoss = (from s in db.Sellers
join d in db.Departments on s.Id equals d.BossId into joinedTable
from jt in joinedTable.DefaultIfEmpty()
where jt.BossId == null
select s.Id).ToList();

How to join 3 tables with lambda expression?

I have a simple LINQ lambda join query but I want to add a 3rd join with a where clause. How do I go about doing that?
Here's my single join query:
var myList = Companies
.Join(
Sectors,
comp => comp.Sector_code,
sect => sect.Sector_code,
(comp, sect) => new {Company = comp, Sector = sect} )
.Select( c => new {
c.Company.Equity_cusip,
c.Company.Company_name,
c.Company.Primary_exchange,
c.Company.Sector_code,
c.Sector.Description
});
I want to add the following SQL command to the above LINQ query and still maintain the projections:
SELECT
sector_code, industry_code
FROM
distribution_sector_industry
WHERE
service = 'numerical'
The 3rd join would be made with Sector table & Distribution_sector_industry on sector_code.
Thanks in advance.
Just a guess:
var myList = Companies
.Join(
Sectors,
comp => comp.Sector_code,
sect => sect.Sector_code,
(comp, sect) => new { Company = comp, Sector = sect })
.Join(
DistributionSectorIndustry.Where(dsi => dsi.Service == "numerical"),
cs => cs.Sector.Sector_code,
dsi => dsi.Sector_code,
(cs, dsi) => new { cs.Company, cs.Sector, IndustryCode = dsi.Industry_code })
.Select(c => new {
c.Company.Equity_cusip,
c.Company.Company_name,
c.Company.Primary_exchange,
c.Company.Sector_code,
c.Sector.Description,
c.IndustryCode
});
Okay, I can't see why you'd want to select sector_code when you already know it, but I think you want this:
var query = from company in Companies
join sector in Sectors
on company.SectorCode equals sector.SectorCode
join industry in DistributionSectorIndustry
on sector.SectorCode equals industry.SectorCode
where industry.Service == "numerical"
select new {
company.EquityCusip,
company.CompanyName,
company.PrimaryExchange,
company.SectorCode,
sector.Description,
industry.IndustryCode
};
Notes:
I've changed it into a query expression as that's a much more readable way of expressing a query like this.
Although the "where" clause comes after the join, assuming this is a LINQ to SQL or Entity Framework query, it shouldn't make any difference
I've lengthened the range variable names for clarity
I've converted your other names into conventional .NET names; you can do this too in your model
For 4 Tables
var query = CurrencyDeposits
.Join(Customers, cd => cd.CustomerId, cus => cus.Id, (cd, cus)
=> new { CurrencyDeposit = cd, Customer = cus })
.Join(Currencies, x => x.CurrencyDeposit.CurrencyId, cr => cr.Id, (x, cr)
=> new { x.CurrencyDeposit, x.Customer, Currency = cr })
.Join(Banks, x => x.CurrencyDeposit.BankId, bn => bn.Id, (x, bn)
=> new { x.CurrencyDeposit, x.Customer, x.Currency, Bank = bn})
.Select(s => new {
s.CurrencyDeposit.Id,
s.Customer.NameSurname,
s.Currency.Code,
s.Bank.BankName,
s.CurrencyDeposit.RequesCode
});
Try something like this...
var myList = ({from a in Companies
join b in Sectors on a.Sector_code equals b.Sector_code
join c in Distribution on b.distribution_code equals a.distribution_code
select new {...});

Translating between LINQ formats

Does anyone know how to write this
var q = from c in customers
join o in orders on c.Key equals o.Key
select new {c.Name, o.OrderNumber};
In this syntax style?
var 1= customers.
.join(???)
.select(???)
I've been googling for a way to do this for days now with now luck. Everyone preferes the first syntax for tutorials, but I find the second much easier to determine order of operation when reading.
The compiler translation process involves using a "transparent identifier" that makes the current customer and order available to the Select method. You can emulate this by making your own:
customers.Join(orders, c => c.Key, o => o.Key, (c, o) => new { c, o })
.Select(x => new { x.c.Name, x.o.OrderNumber });
Instead, you could just move your Name/OrderNumber projection up into the Join call:
customers.Join(orders, c => c.Key, o => o.Key, (c, o) => new { c.Name, o.OrderNumber });
This just takes a single call to Enumerable.Join:
var q = customers.Join(
orders,
c => c.Key,
o => o.Key,
(c, o) => new {c.Name, o.OrderNumber}
);
You might also check out LinqPad . It has a small lambda button for the bottom half of the screen, and it translates the linq query to chain methods :
from p in PropertyListings
from rl in p.ResidentialListings
select new {p.YearBuilt,p.ListingUrl}
got translated to :
PropertyListings
.SelectMany (
p => p.ResidentialListings,
(p, rl) =>
new
{
YearBuilt = p.YearBuilt,
ListingUrl = p.ListingUrl
}
)

Categories

Resources