Convert special SQL query to Linq - c#

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
};

Related

T-SQL to LINQ query that has a case statement and a subquery in it

I'm a complete beginner in LINQ and I would like to convert this T-SQL query in LINQ
SELECT
CASE
WHEN D.IsBaseloadDefined = 1
THEN COUNT(D.DeviceID)
ELSE
(SELECT COUNT(DORG.DeviceID)
FROM DeviceOrganization DORG
INNER JOIN Organization ORG ON DORG.OrganizationID = ORG.OrganizationID
INNER JOIN BaseloadOrganization BO ON ORG.BaseloadOrganizationId = BO.OrganizationID
INNER JOIN Baseload BL ON BO.BaseloadID = BL.BaseloadID
WHERE DORG.DeviceID = D.DeviceID
AND BL.RecursUntil >= GETDATE()
GROUP BY DORG.DeviceID)
END AS [Nb of devices]
FROM DeviceOrganization DO
INNER JOIN Device D ON DO.DeviceID = D.DeviceID
LEFT JOIN BaseloadDevice BD ON D.DeviceID = BD.DeviceID
LEFT JOIN Baseload B ON BD.BaseloadID = B.BaseloadID AND B.RecursUntil >= GETDATE()
INNER JOIN OrganizationHierarchy OH ON DO.OrganizationID = OH.SubOrganizationID
WHERE OH.OrganizationID = 6
AND D.IsActive = 1
group by D.DeviceID, D.IsBaseloadDefined
I've seen this topic but I don't really understand the answer
The only thing I could do so far is this, and now I'm completly lost
from deviceO in _context.DeviceOrganizations
join d in _context.Devices on deviceO.DeviceID equals d.DeviceID
join bd in _context.BaseloadDevices on d.DeviceID equals bd.DeviceID
join b in _context.Baseloads on bd.BaseloadID equals b.BaseloadID
join oh in _context.OrganizationHierarchies on deviceO.OrganizationID equals oh.SubOrganizationID
where oh.OrganizationID == OrganizationId
where d.IsActive == true
where b.RecursUntil <= DateTime.Now
group d.DeviceID by d.DeviceID).Count()
Instead of get count of group
group d.DeviceID by d.DeviceID).Count()
you should save result in variable
var data = from deviceO in _context.DeviceOrganizations
join d in _context.Devices on deviceO.DeviceID equals d.DeviceID
join bd in _context.BaseloadDevices on d.DeviceID equals bd.DeviceID
join b in _context.Baseloads on bd.BaseloadID equals b.BaseloadID
join oh in _context.OrganizationHierarchies on deviceO.OrganizationID equals oh.SubOrganizationID
where oh.OrganizationID == OrganizationId
where d.IsActive == true
where b.RecursUntil <= DateTime.Now
and then you should do something like this:
//group by 2 properties
var result = data.GroupBy(d => new { d.DeviceID, d.IsBaseloadDefined })
.Select(g =>
{
//for each group we get IsBaseloadDefined property
var IsBaseloadDefined = g.Key.IsBaseloadDefined;
if (IsBaseloadDefined == 1)
{
return g.Count();
}
else
{
// here another select that return count:
//(SELECT COUNT(DORG.DeviceID)
//FROM DeviceOrganization DORG
// INNER JOIN Organization ORG ON DORG.OrganizationID = ORG.OrganizationID
//INNER JOIN BaseloadOrganization BO ON ORG.BaseloadOrganizationId = BO.OrganizationID
//INNER JOIN Baseload BL ON BO.BaseloadID = BL.BaseloadID
//WHERE DORG.DeviceID = D.DeviceID
//AND BL.RecursUntil >= GETDATE()
//GROUP BY DORG.DeviceID)
//in this query you should return Count() of group
return 1; //return group.Count() instead 1
}
});
I hope this helps you

How to Join LINQ to another LINQ

i have a query like this
WITH CTE_KELOMPOKINFORMASI (KelompokInformasi, XBRLItem_ItemId)
AS (
SELECT a.Id AS KelompokInformasi, c.XBRLItem_ItemId
FROM XBRLNamespaces a INNER JOIN XBRLHypercubes b
ON a.XBRLView_ViewId = b.XBRLView_ViewId
INNER JOIN XBRLHypercubeDimensionItems c
ON b.XBRLHypercubeId = c.XBRLHypercube_XBRLHypercubeId
WHERE a.Id like '%KBIK_AAKL%')
SELECT f.KelompokInformasi, e.Name AS DimensionName, c.Id AS Domain,
d.Text AS Description FROM [dbo].[XBRLDefinitionRoleDomainItems] a
INNER JOIN [dbo].[XBRLDefinitionRoleDimensionItems] b
ON a.XBRLDefinitionRole_DefinitionRoleId = b.XBRLDefinitionRole_DefinitionRoleId
INNER JOIN XBRLItems c ON a.XBRLItem_ItemId = c.ItemId
INNER JOIN XBRLLabels d
ON a.XBRLItem_ItemId = d.XBRLItem_ItemId
INNER JOIN XBRLItems e
ON b.XBRLItem_ItemId=e.ItemId
INNER JOIN CTE_KELOMPOKINFORMASI f
ON b.XBRLItem_ItemId=f.XBRLItem_ItemId
WHERE b.XBRLItem_ItemId=f.XBRLItem_ItemId
i want to move this sql query to linq, i realized that CTE is impossible in LINQ. So i divide into 2 parts. First i create a var like this:
var KelompokInformasi = from x in ent.XBRLNamespaces
join y in ent.XBRLHypercubes on x.XBRLView_ViewId equals y.XBRLView_ViewId
join z in ent.XBRLHypercubeDimensionItems on y.XBRLHypercubeId equals z.XBRLHypercube_XBRLHypercubeId
where x.Id.Contains("KBIK")
select new
{
x.Id,
y.XBRLItem_ItemId
};
and in second part i create:
_list = (from a in ent.XBRLDefinitionRoleDomainItems
join b in ent.XBRLDefinitionRoleDimensionItems on a.XBRLDefinitionRole_DefinitionRoleId equals b.XBRLDefinitionRole_DefinitionRoleId
join c in ent.XBRLItems on a.XBRLItem_ItemId equals c.ItemId
join d in ent.XBRLLabels on a.XBRLItem_ItemId equals d.XBRLItem_ItemId
join e in ent.XBRLItems on b.XBRLItem_ItemId equals e.ItemId
join f in KelompokInformasi on b.XBRLItem_ItemId equals (int)f.XBRLItem_ItemId
where (b.XBRLItem_ItemId == (int)f.XBRLItem_ItemId)
select new MappingDomainRepository
{
KI = f.Id,
Dimension = e.Name,
Domain = c.Id,
Description = d.Text
}).ToList();
Where _list is from List<MappingDomainRepository> _list = new List<MappingDomainRepository>();
in my code above, i want to join my _list to var KelompokInformasi. In var kelompokInformasi I've got 47 rows but in _list I've got 0 data return.
What's wrong in my code? is it possible to join my _list to var kelompokInformasi?
You need to change the second part to:
var other = (from a in ent.XBRLDefinitionRoleDomainItems
join b in ent.XBRLDefinitionRoleDimensionItems on a.XBRLDefinitionRole_DefinitionRoleId equals b.XBRLDefinitionRole_DefinitionRoleId
join c in ent.XBRLItems on a.XBRLItem_ItemId equals c.ItemId
join d in ent.XBRLLabels on a.XBRLItem_ItemId equals d.XBRLItem_ItemId
join e in ent.XBRLItems on b.XBRLItem_ItemId equals e.ItemId
join f in KelompokInformasi on b.XBRLItem_ItemId equals (int)f.XBRLItem_ItemId
where (b.XBRLItem_ItemId == (int)f.XBRLItem_ItemId)
select new MappingDomainRepository
{
KI = f.Id,
Dimension = e.Name,
Domain = c.Id,
Description = d.Text,
XBRLItem_ItemId = a.XBRLItem_ItemId
};
...which adds in the XBRLItem_ItemId which use to join to the CTE.
Then join the two together. We have other (above) and KelompokInformasi from the CTE:
var result = from x in KelompokInformasi
join o in other on x.XBRLItem_ItemId equals o.XBRLItem_ItemId
select new {KelompokInformasi = o.KelompokInformasi,
DimensionName = o.Name,
Domain = o.Id,
Description = o.Text
};
..which appears to be the columns you exentually select.

How can i join two table in Linq and display the join to Data GridView?

I'm trying to join two tables and to display the Join result into GridView in WinForms, but something is going wrong...
it's not giving me Error message or something, Please help!!
my code :
var temp = teacherCmbBx.SelectedItem.ToString();
var temp2 = (from c in context.Teachers
where temp == c.FirstName
select c).ToList();
long num = temp2[0].ID;
var teacherGroup = (from t in context.Teachers
join g in context.Groups on t.ID equals g.TeacherID
where num == t.ID
select t);
teachergrpGridView.DataSource = teacherGroup;
string temp3 = (string)teachergrpGridView.Rows[rowNum].Cells[0].Value;
You are almost there. You are just missing .ToList()
var teacherGroup = (from t in context.Teachers
join g in context.Groups on t.ID equals g.TeacherID
where num == t.ID
select t).ToList();
teachergrpGridView.DataSource = teacherGroup;
var teacherGroup = from t in context.Teachers
join g in context.Groups on t.ID equals g.TeacherID
where num == t.ID
select new {
t.Id ,
g.Name,
t.xxxx
};

Linq to entities query with nested query on the same table

I have a SQL query:
SELECT distinct A.stock_value_site,
A.BALANCE_QUANTITY,
A.BALANCE_NOMINAL_VALUE,
A.BALANCE_INDEXED_VALUE,
V.STOCK_VALUE_ORDER,
U.BALANCE_QUANTITY
FROM svr A,
svt V,
svu U
WHERE V.Code = 500 and
A.Id = U.ID (+) and
A.Id = (SELECT max(B.id)
FROM svr B,
sts
WHERE A.stock_value_site = B.stock_value_site and
B.Id = sts.ID(+) and
B.item = _item and
B.date < _from_date and
B.Id IS NULL)
I tried to convert this query to Linq to entities:
var data = (from A in _context.svr
join V in _context.svt on A.svtId equals V.Code
join U in _context.svu on A.Id equals U.Id into groupA
from gA in groupA.DefaultIfEmpty()
where V.Code == _openBalanceRecordId &&
A.Id == (from B in _context.svr
join st in _context.sts on B.Id equals st.Id into groupB
from gB in groupB.DefaultIfEmpty()
where A.svsId == B.svsId &&
B.ItemId == _item &&
B.Date < _startDate.Date
select B.Id).Max()
select new
{
A.stock_value_site,
A.BALANCE_QUANTITY,
A.BALANCE_NOMINAL_VALUE,
A.BALANCE_INDEXED_VALUE,
V.STOCK_VALUE_ORDER,
gA == null ? 0 : gA.BALANCE_QUANTITY
}).Distinct().ToList();
When I run the SQL query in oracle I get 33 records back. But when I run it using Linq to entities I don't get any record.
What am I doing wrong?
I believe there are still some issues with you're original query, if I understand what you're trying to do, this should work better:
var results =
(from a in _context.svr
from v in _context.svt.Where(t => t.Code == 500)
join u in _context.svu on u.Id equals a.Id into gU
from x in gU.DefaultIfEmpty()
where a.Id ==
(from b in _context.svr
join s in _context.sts on b.Id equals s.Id
where b.item = _item
and b.date < _from_date
and b.svsId == a.svsId
select b.Id).Max()
select new
{
a.stock_value_site,
a.BALANCE_QUANTITY,
a.BALANCE_NOMINAL_VALUE,
a.BALANCE_INDEXED_VALUE,
v.STOCK_VALUE_ORDER,
x == null ? 0 : x.BALANCE_QUANTITY
}).Distinct().ToList();
Or possibly this:
var results =
(from a in _context.svr
from v in _context.svt.Where(t => t.Code == 500)
join u in _context.svu on u.Id equals a.Id into gU
from x in gU.DefaultIfEmpty()
let subQuery =
(from b in _context.svr
join s in _context.sts on b.Id equals s.Id
where b.item = _item
and b.date < _from_date
select new { b.Id, b.svsId })
join y in subQuery on a.svsId equals y.svsId into gY
where a.Id = y.Max(b => b.Id)
select new
{
a.stock_value_site,
a.BALANCE_QUANTITY,
a.BALANCE_NOMINAL_VALUE,
a.BALANCE_INDEXED_VALUE,
v.STOCK_VALUE_ORDER,
x == null ? 0 : x.BALANCE_QUANTITY
}).Distinct().ToList();

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")

Categories