SQL query to LINQ expression - c#

I cannot make the following query into LINQ expression. Could you help me ?
SELECT Employee_Id_FK from TimeRegistrations as tr
JOIN Employees em ON tr.Employee_Id_FK = em.id
JOIN Managers m ON em.Manager_Id_FK = m.id
WHERE m.id = 4
This is what I have so far :
var result = from t in DB.TimeRegistrations
join Employees in DB.TimeRegistrations on t.Employee_Id_FK equals Employees.id
join Managers in DB.Managers on ..... ;
// Display results.
foreach (var r in result)
{
Console.WriteLine(r);
}

In case your db has foreign keys:
var result =from t1 in DB.TimeRegistrations
join t2 in t1.Employees
join t3 in t2.Managers
where t3.id == "4"
select t1
in case it does not:
var result =from t1 in DB.TimeRegistrations
join t2 in DB.Employees on t1.Employee_Id_FK equals t2.id
join t3 in DB.Managers on t2.id equals t3.Manager_Id_FK
where t3.id == "4"
select t1
However shorter way will be:
var result = DB.Managers.Find(4).Employees.SelectMany(e=>e.TimeRegistrations)
Or not that straight forward way:
var result = DB.TimeRegistrations
.Where(t=>t.Employees.Any(e=>e.Managers.Any(m=>m.id == 4)))

Related

convert Conditional Join in SQL to Linq

I have a normally simple looking query in SQL as:
SELECT table1.Id, count(table2.col) AS OrderCol
FROM table1
LEFT JOIN table2 ON table1.Id = table2.Id
LEFT JOIN table3 ON table2.Id = table3.Id AND table2.condition = 3 //some integer value
GROUP BY table1.Id
ORDER BY count(table2.col) DESC
When AND clause appears inside join, I am not sure about how to convert this to LINQ...
How to achieve it?
It goes something like:
from t1 in db.Table1
join t2 in db.Table2 on t1.field equals t2.field
select new { t1.field2, t2.field3}
Try this:
var answer = (from t1 in table1
join t2 in table2 on t1.Id equals t2.Id into subData1
from t2sub in subData1.DefaultIfEmpty()
join t3 in table3 on new { Id = t2sub == null ? 0 : t2sub.Id, condition = t2sub == null ? 0 : t2sub.condition } equals new { t3.Id, condition = 3 } into subData
from t3sub in subData.DefaultIfEmpty()
group new { t1, t2sub } by t1.Id into subGroup
orderby subGroup.Count(x => x.t2sub != null) descending
select new {
Id = subGroup.Key,
OrderCol = subGroup.Count(x => x.t2sub != null)
}).ToList();

Linq - Inner Join not retrieving all records from left table

I have done an inner join, it shows only the matching record with following query :-
var data = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp
on t1.Field equals t2.Fld
where t1.Id == Id &&
t2.Id == Id
select new Settings { Master = t1.Labelname, OrderNo = t2.OrderNo};
I want all the records from tblEmp & only matching records from tblHelp.
How to do this?
Use as
var data = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp
on t1.Field equals t2.Fld into u
from t2 in u.DefaultIfEmpty()
where t1.Id == Id &&
t2.Id == Id
select new Settings { Master = t1.Labelname, OrderNo = t2.OrderNo};
Try this
var data = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp
on t1.Field equals t2.Fld into u
from t2 in u.DefaultIfEmpty()
where t1.Id == Id
orderby columnname // Added Order By
select new Settings { Master = t1.Labelname, OrderNo = t2.OrderNo==null ?"":t2.OrderNo};
var query = from t1 in ctx.tblEmp
join t2 in ctx.tblHelp on t1 equals t2.Fld into tempGroup
from subpet in tempGroup.DefaultIfEmpty()
select new { t1.Labelname, OrderNo = (subpet == null ? String.Empty : subpet.OrderNo) };

How to do linq joins with multiple conditions + ORs

I would like to know how to do a linq join with multiple conditions and ORs.
Example:
var i = (from d in context.Table1
join b in context.Table2
on new {r1 = d.col1, r2 = d.col2}
equals new {r1 = b.col1, r2 = b.col2}
|| b.col3.ToLower() equals "xyz"
into bd
from k in bd.DefaultIfEmpty()
The ORs part is blowing up.
SQL example:
SELECT * FROM Table1 T1
LEFT JOIN Table2 T2 ON (T1.Col1 = T2.Col1 AND T1.Col2 =T2.Col2)
OR (T1.Col1 = T2.Col1 AND T2.Col2 = 'XYZ')
Explanation:
T1.Col1 must match T2.COl1 - REQUIRED JOIN
Then
T1.Col2 has to match T2.Col2 unless T2.COl2 = "XYZ" then join only on Col1
Try moving the "join" into the "Where" clause ala ANSI 82:
var i = (from d in context.Table1
from b in context.Table2
where (b == null)
|| (d.col1 = b.col1 && d.col2 == b.col2 )
|| (b.col3.ToLower() == "xyz")

Convert special SQL query to Linq

do you know how write this SQL Query to linq ?
SELECT *
FROM
a
INNER JOIN b
ON a.FkSubmissionId = b.Id
RIGHT JOIN c
ON a.FkItemId = c.Id
WHERE
(b.FkUserId = '...' OR b.FkUserId is null)
and
(c.FkTenderId = 2)
I use Linquer and the best I have from the tool is that :
Linq :
from
items in _context.Items
from
si in _context.si
join s in _context.s
on new { fki = si.fki } equals new { fki = s.Id }
into
submissions_join
from
s in submissions_join.DefaultIfEmpty()
...
Result in SQL :
SELECT *
FROM
[Items] AS [t0]
CROSS JOIN [SubmissionsItems] AS [t1]
LEFT OUTER JOIN [Submissions] AS [t2]
ON [t1].[FkSubmissionId] = [t2].[Id]
WHERE
(([t2].[FkUserId] = #p0) OR (([t2].[FkUserId]) IS NULL))
AND
([t0].[FkTenderId] = #p1)
So the final result it not what I get from the query I need...
Thank you for your help !!!
Try this:
var part1 =
from x in a
join y in b on x.FkSubmissionId equals y.Id
where b.FkUserId = "..."
select new {x, y};
var part2 =
from c in z
where c.FkTenderId == 2
join xy in part1
on z.Id equals xy.x.FkItemId
into xys
from xy in xys.DefaultIfEmpty()
select new {xy.x, xy.y, z};
I would reorder your query so you can use a left join instead of a right join
var query = from c in context.C
from a in context.A.Where(x => c.Id == x.FkItemId)
.DefaultIfEmpty()
join b in context.B on a.FkSubmissionId equals b.id
where b.FkUserId == '...' || b.FkUserId == null
where c.FkTenderId == 2
select new {
a,
b,
c
};

LINQ: Using INNER JOIN, Group and SUM

I am trying to perform the following SQL using LINQ and the closest I got was doing cross joins and sum calculations. I know there has to be a better way to write it so I am turning to the stack team for help.
SELECT T1.Column1, T1.Column2, SUM(T3.Column1) AS Amount
FROM T1
INNER JOIN T2
ON T1.T1ID = T2.T1ID
INNER JOIN T3
ON T2.T3ID = T3.T3ID
GROUP BY T1.Column1, T1.Column2
What I have been trying is the following LINQ code
var qTotal = from T2 in context.T2
from T3 in context.T3
where T3.T3ID == T3.T3ID
group T3 by T2.T1ID into gT2T3
from T1 in context.T1
where gT2T3.Key.Equals(T1.T1ID)
select new { T1.Column1,T1.Column2,Amount = gT2T3.Sum(t => t.Column1)};
I know there has to be a better way to write it, I just do not know how, any help would be great!
Try this:
var total = from T1 in context.T1
join T2 in context.T2 on T1.T2ID equals T2.T2ID
join T3 in context.T3 on T2.T3ID equals T3.T3ID
group T3 by new { T1.Column1, T1.Column2 } into g
select new {
Column1 = T1.Column1,
Column2 = T2.Column2,
Amount = g.Sum(t3 => t3.Column1)
};
For me (using 4.0), the following works.
var total = from T1 in context.T1
join T2 in context.T2 on T1.T2ID equals T2.T2ID
join T3 in context.T3 on T2.T3ID equals T3.T3ID
group T3 by new { T1.Column1, T1.Column2 } into g
select new {
Column1 = g.Key.Column1,
Column2 = g.Key.Column2,
Amount = g.Sum(t3 => t3.Column1)
};
Below code is working for me :
var credit = (from bm in BulkMessage
join sms in SMS on bm.BulkMessageId equals sms.BulkMessageId
where bm.ProfileId == pid && bm.IsActive == true
group sms by sms.SMSCredit into g
select new { SMSCredits = g.Sum(s => s.SMSCredit) }).FirstOrDefault();

Categories