Left join with LINQ with entityframework - linq

I try to make a left query with linq:
public IQueryable<Mutatie> GetMutaties()
{
var query = (from m in context.Mutatie
join d in context.tblDienstverband on m.fkDienstVerbandID equals d.DienstverbandID
join med in context.tblMedewerker on d.fkMedewerkerID equals med.MedewerkerID
where med.fkKlantID == this.klantId
select m).Include(d => d.fkDienstVerbandID);
return query;
}
But how to make this to have a left query?
Thank you
I have it now like this:
var query = (from m in context.Mutatie
join d in context.tblDienstverband on m.fkDienstVerbandID equals d.DienstverbandID into grp
from d in grp.DefaultIfEmpty()
join med in context.tblMedewerker on d.fkMedewerkerID equals med.MedewerkerID into grp1
from med in grp.DefaultIfEmpty()
where med.fkMedewerkerID == this.klantId
select new { m, d, med });
return query;

It should like this:
NOTE: d and med are null if no row match
public IQueryable<Mutatie> GetMutaties()
{
var query = (from m in context.Mutatie
join d in context.tblDienstverband on m.fkDienstVerbandID equals d.DienstverbandID into grp
from d in grp.DefaultIfEmpty()
join med in context.tblMedewerker on d.fkMedewerkerID equals med.MedewerkerID into grp_med
from med in grp_med.DefaultIfEmpty()
where med.fkKlantID == this.klantId
//select new { m, d, med };
select m;
return query;
}

Related

Oracle co related query?

How does co-related query works? Does inner query iterate according to outer query rows? Suppose I have student table with only 1 ID columns with vlaues 1, 2, 3. Can any body gives pictorial example?
select count(*)
from student s where s.sid < any (select s1.id from student s1 where s1.id < s.id);
The correlated subquery is (theoretically - without considering possible optimization) performed once for each row of the main table (s).
For the s.ID = 1 the subquery returns no row (s1.ID < 1 return nothing)
for the s.ID = 2 it returns 1 and (predicate s1.id < 2)
for the s.ID = 3 it returns 1,2
Therefore the first row (s.ID=1) is not selected (the subquery return no row),
for the second row (s.ID =2) the predicate is s.id < any ( 1 ) which is rewritten to s.id < 1 see rules for ANY
and the row is not selected as 2 < 1 is FALSE
for the third row (s.ID = 3) the predicate is s.id < any ( 1,2 ) which is rewritten to s.id < 1 OR s.id < 2 which is FLASE as well.
So the query
create table student as
select rownum id from dual connect by level <= 3;
select *
from student s where s.id < any (select s1.id from student s1 where s1.id < s.id);
return empty result (no rows).

Oracle Inner join on multiple tables returning null values

I am working on a sql inner join query which should return MAX elements from other tables. Tables B, C, D, E might be empty. In that case null should also be printed in output.
This is what I tried.
SELECT A.INDEX, A.CODE, MAX(B.DAY), MAX(C.TIMESTAMP), MAX(D.TIMESTAMP)
FROM A
INNER JOIN B
INNER JOIN C
INNER JOIN D
INNER JOIN E
ON A.INDEX = B.INDEX
ON A.INDEX = C.INDEX
ON A.INDEX = D.INDEX
ON A.INDEX = E.INDEX AND E.FUNCTION = 0;
Table definitions:
A
-------
INDEX NOT NULL NUMBER(10)
CODE NOT NULL VARCHAR2(16)
B
--------
INDEX NUMBER(10)
DAY NUMBER(10)
C
---------
INDEX NUMBER(10)
TIMESTAMP TIMESTAMP(6)
D
---------
INDEX NUMBER(10)
TIMESTAMP TIMESTAMP(6)
E
----------
INDEX NUMBER(10)
FUNCTION NUMBER(5)
In that case, consider doing a LEFT OUTER JOIN instead like
FROM A
LEFT JOIN B
So for your case
SELECT A.INDEX, A.CODE, MAX(B.DAY), MAX(C.TIMESTAMP), MAX(D.TIMESTAMP)
FROM A
LEFT JOIN B ON A.INDEX = B.INDEX
LEFT JOIN C ON A.INDEX = C.INDEX
LEFT JOIN D ON A.INDEX = D.INDEX
LEFT JOIN E ON A.INDEX = E.INDEX
AND E.FUNCTION = 0;

How to write order by in linq

This code output is like this
a 1
b 12
I wont to get out put like this
b 12
a 1
Query:
var x1 = (from v in db3.VoteRecords
join v2 in db3.Partis on v.PartiID equals v2.ID
where v.ProvinceID == (int)cmbProvience.SelectedValue
&& v.DistrictID == (int)cmbDistrict.SelectedValue
group v by new { v2.PartiName } into g
select new
{
Parti = g.Key.PartiName,
Votes = (from vt in g
select g.Key.PartiName).Count()
});
dataGridView1.DataSource = x1;
You can add this at the end
{
Parti = g.Key.PartiName,
Votes = (from vt in g
select g.Key.PartiName).Count()
}).OrderByDescending(l =>l.Parti);
If you want to order by the Votes column. Do this:
{
Parti = g.Key.PartiName,
Votes = (from vt in g
select g.Key.PartiName).Count()
}).OrderByDescending(l =>l.Votes);
Or if you first want to order by Parti and then by Votes do this:
{
Parti = g.Key.PartiName,
Votes = (from vt in g
select g.Key.PartiName).Count()
}).OrderByDescending(l =>l.Parti).ThenByDescending (l =>l.Votes);
Or if you first want to order by Votes and then by Parti do this:
{
Parti = g.Key.PartiName,
Votes = (from vt in g
select g.Key.PartiName).Count()
}).OrderByDescending(l =>l.Votes ).ThenByDescending (l =>l.Parti);

Linq left joining with non trivial condition

This is fine, it produces a left join
var q =
from c in categories
join p in products
on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };
But what about if I wanted to do something like this:
...
on p.date between c.startdate and c.enddate
...
var q =
from c in categories
join p in products
on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
where p.date >= c.startdate && p.date <= c.enddate
select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };

Convert to Lambda expression

I have the following expression
var q = from c in D1
join dp in
(from e in E1
group e by e.ID into g
select new { ID = g.Key, Cnt = g.Count() })
on c.ID
equals dp.ID
into dpp from v in dpp.DefaultIfEmpty()
select new { c.ID, Cnt= v.Cnt ?? 0 };
How can i convert this to Lambda expression?
Here's one way to go. This kind-of matches the above.
var subquery = E1
.GroupBy(e => e.Id)
.Select(g => new { ID = g.Key, Cnt = g.Count()});
//.ToList();
var q = D1
.GroupJoin(
subquery,
c => c.ID,
dp => dp.ID,
(c, g) => new {ID = c.ID, Cnt=g.Any() ? g.First().Cnt : 0 }
)
After refactoring, I came up with this:
var q = D1
.GroupJoin(
E1,
d => d.ID,
e => e.ID,
(d, g) => new {ID = d.ID, Cnt = g.Count()}
);
For comparision, the query comprehension form is:
var q = from d in D1
join e in E1 on d.ID equals e.ID into g
select new {ID = d.ID, Cnt = g.Count()};
Why would you want to convert it?
For complex queries like this one the query syntax you have used here is invariably clearer.

Resources