I have an linq query like this :
var query = from Romm in RoMM
join rfrsa in RoMmfrsa on Romm.RoMmid equals rfrsa.RoMmid
join frsa in Frsa on rfrsa.Frsaid equals frsa.Fraid
join fra in Fra on frsa.Fraid equals fra.Fraid
where Romm.ActTypeId == 2 && Romm.SegmentId == 4
select new
{
Romm.ActTypeId,
Romm.RoMmid,
frsa.Fraid,
frsa.Frsaid,
Romm.ImpactId
};
And I have SQL code as below :
SELECT romm.ROMMID
, frsa.FRAID
, frsa.FRSAID
, romm.ImpactID
FROM RoMM AS romm
INNER
JOIN RoMMFRSA AS rfrsa
ON romm.RoMMID = rfrsa.RoMMID
INNER
JOIN FRSA AS frsa
ON rfrsa.frsaid = frsa.frsaid
INNER
JOIN FRA AS fra
ON frsa.FRAID = fra.FRAID
WHERE romm.acttypeid = 2
AND romm.segmentid = 4
The SQL only shows one row (which is correct), the linq shows the correct row and then it displays about another 3 rows which is not what we need. I need the linq to show one row which is correct with the SQL. Is this because of maybe many-many relationships ?
Looks like a typo in either the C# or the SQL join:
SQL: ON rfrsa.frsaid = frsa.frsaid
C#: rfrsa.Frsaid equals frsa.Fraid
^^^^^^
mismatch here
Just to set the context a little, I'm trying to use queries with mysql that use Late row lookup as shown in this article
https://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/
but that's a story for another day but the idea is that you do a key search on the table and then join it onto the whole table to force a late row lookup and the problem is coming from my LINQ queries when joined together.
-- Key search query --
Calling Code
IQueryable<int> keySearch = _defaultQueryFactory.Load(ContextEnums.ClientContext, MapEntityToDTO(), whereStatement, clientID).OrderBy(orderBy).Skip(startRow).Take(pageSize).Select(x => x.ID);
Resulting Query
SELECT
`Extent1`.`Sys_InvoiceID`
FROM `tblinvoice` AS `Extent1`
WHERE 3 = `Extent1`.`FK_StatusID`
ORDER BY
`Extent1`.`InvoiceDate` ASC LIMIT 0,430
-- Full Table Search --
Calling Code
IQueryable<InvoiceDTOModel> tableSearch = _defaultQueryFactory.Load(ContextEnums.ClientContext, MapEntityToDTO(), null, clientID, true).OrderBy(orderBy);
Resulting Query
SELECT
`Extent1`.`ID`,
`Extent1`.`C1`,
`Extent1`.`C2`,
`Extent1`.`C3`,
`Extent1`.`C4`,
`Extent1`.`C5`,
`Extent1`.`C6`,
`Extent2`.`SID`,
`Extent2`.`S1,
`Extent2`.`S2`,
`Extent2`.`S3`,
`Extent3`.`EID`,
`Extent3`.`E1`,
`Extent4`.`DID`,
`Extent4`.`D1`,
`Extent4`.`D2`,
`Extent4`.`D3`,
`Extent4`.`D4`,
`Extent4`.`D5`
FROM `tbl1` AS `Extent1` INNER JOIN `tbl2` AS `Extent2` ON `Extent1`.`SID` = `Extent2`.`SID` INNER JOIN `tbl3` AS `Extent3` ON `Extent1`.`EID` = `Extent3`.`EID` LEFT OUTER JOIN `tbl4` AS `Extent4` ON `Extent1`.`ID` = `Extent4`.`DID`
ORDER BY
`Extent1`.`C4` ASC
-- Joining the Two Together --
Calling Code
keySearch.Join(tableSearch, key => key, table => table.ID, (key, table) => table).OrderBy(orderBy).ToListAsync();
Resulting Query
SELECT
`Join3`.`ID`,
`Join3`.`C1`,
`Join3`.`C1`,
`Join3`.`C1`,
`Join3`.`C1`,
`Join3`.`C1`,
`Join3`.`C1`,
`Join3`.`SID`,
`Join3`.`S1,
`Join3`.`S2`,
`Join3`.`S3`,
`Join3`.`EID`,
`Join3`.`E1`,
`Join3`.`DID`,
`Join3`.`D1`,
`Join3`.`D2`,
`Join3`.`D3`,
`Join3`.`D4`,
`Join3`.`D5`
FROM (
`Extent1`.`ID`,
`Extent1`.`C1`,
`Extent1`.`C2`,
`Extent1`.`C3`,
`Extent1`.`C4`,
`Extent1`.`C5`,
`Extent1`.`C6`
FROM `tblinvoice` AS `Extent1`
WHERE 3 = `Extent1`.`EID`
ORDER BY
`Extent1`.`C4` ASC LIMIT 0,430) AS `Limit1` INNER JOIN (SELECT
`Extent1`.`ID`,
`Extent1`.`C1`,
`Extent1`.`C2`,
`Extent1`.`C3`,
`Extent1`.`C4`,
`Extent1`.`C5`,
`Extent1`.`C6`,
`Extent2`.`SID`,
`Extent2`.`S1,
`Extent2`.`S2`,
`Extent2`.`S3`,
`Extent3`.`EID`,
`Extent3`.`E1`,
`Extent4`.`DID`,
`Extent4`.`D1`,
`Extent4`.`D2`,
`Extent4`.`D3`,
`Extent4`.`D4`,
`Extent4`.`D5`
FROM `tbl1` AS `Extent2` INNER JOIN `tbl2` AS `Extent3` ON `Extent2`.`SID` = `Extent3`.`SID` INNER JOIN `tblstatus` AS `Extent4` ON `Extent2`.`EID` = `Extent4`.`EID` LEFT OUTER JOIN `tbl3` AS `Extent5` ON `Extent2`.`ID` = `Extent5`.`DID`) AS `Join3` ON `Limit1`.`ID` = `Join3`.`ID`
ORDER BY
`Join3`.`C4` ASC
Basically the inner select brings back
FROM (
`Extent1`.`ID`,
`Extent1`.`C1`,
`Extent1`.`C2`,
`Extent1`.`C3`,
`Extent1`.`C4`,
`Extent1`.`C5`,
`Extent1`.`C6`
FROM `tblinvoice` AS `Extent1`
WHERE 3 = `Extent1`.`EID`
ORDER BY
`Extent1`.`C4` ASC LIMIT 0,430) AS `Limit1`
Instead of
FROM (
`Extent1`.`ID`,
FROM `tblinvoice` AS `Extent1`
WHERE 3 = `Extent1`.`EID`
ORDER BY
`Extent1`.`C4` ASC LIMIT 0,430) AS `Limit1`
--Note--
The actual query selects around 15 columns, I've just shortened it to this example, it has an effect on the search as the dataset grows in size and it shouldn't be selecting all of the fields but i suspect there's an error in my join.
Any help is much appreciated.
I have a query that's something like this.
Select a.*
from table1 a
inner join table2 b on a.field1 = b.field1
inner join table3 c on b.field2 = c.field2
where b.field4 = beta and c.field5 = gamma.
On LINQ, I tried to do that this way:
var query = (from a in table1
join b in table2 on a["field1"] equals b["field1"]
join c in table3 on b["field2"] equals c["field2"]
where (b["field4"] == beta && c["field5"] == gamma)
select a).ToList();
But for some reason, when I try to do this I get an error that says that the entity "table2" doesn't have the field Name = "field5", as though as the where clause was all about the last joined table and the other ones were unaccessible. Furthermore, the compiler doesn't seem to notice neither, because it lets me write c["field5"] == gamma with no warning.
Any ideas? Am I writing this wrong?
Thanks
See these links:
How to: Perform Inner Joins (C# Programming Guide)
What is the syntax for an inner join in linq to sql?
Why you don't create View in database, and Select your data from View in LINQ?
I have a SQL query that I am trying to convert to LINQ:
SELECT * FROM TABLE1
WHERE LICENSE_RTK NOT IN(
SELECT KEY_VALUE FROM TABLE2
WHERE REFERENCE_RTK = 'FOO')
So I wrote one query for inner query and then one query for the outer one and used Except:
var insideQuery = (from pkcr in this.Repository.Context.TABLE2 where pkcr.Reference_RTK == "FOO" select pkcr.Key_Value);
var outerQuery = (from pl in this.Repository.Context.TABLE1 select pl).Except(insideQuery);
But this is wrong. Cannot even compile it. What is the correct way of writing this?
You cannot compile second query, because Except should be used on Queryables of same type. But you are trying to apply it on Queryable<TABLE1> and Queryable<TypeOfTABLE2Key_Value>. Also I think you should use Contains here:
var keys = from pkcr in this.Repository.Context.TABLE2
where pkcr.Reference_RTK == "FOO"
select pkcr.Key_Value;
var query = from pl in this.Repository.Context.TABLE1
where !keys.Contains(pl.License_RTK)
select pl;
NOTE: Generated query will be NOT EXISTS instead of NOT IN, but that's what you want
SELECT * FROM FROM [dbo].[TABLE1] AS [Extent1]
WHERE NOT EXISTS
(SELECT 1 AS [C1]
FROM [dbo].[TABLE2] AS [Extent2]
WHERE ([Extent2].[Reference_RTK] == #p0) AND
([Extent2].[Key_Value] = [Extent1].[License_RTK]))
This might be one of those situations where plain SQL commands are better than LINQ. Here's a simplified version of the SQL statement I'm trying to translate:
SELECT * FROM IDTable AS idt
INNER JOIN NameTable AS nt ON nt.IDTableID=idt.Id
AND nt.Id= (SELECT TOP(1) Id
FROM NameTable AS nt2
WHERE nt2.IDTableID=11 ORDER BY nt2.DateInserted DESC)
I have the LINQ query to pull records when just joining on IDs and I've seen how to join on multiple columns, but I have no idea how to plug the subquery into the mix.
If this isnt entirely clear, please let me know and I'll edit to elaborate.
Maybe something like this?
var results = from id in db.IDTable
join n in db.NameTable on id.Id equals n.IDTableID
where n.Id = (
from n2 in db.NameTable
where n2.IDTableID = 11
orderby n2.DateInserted desc
).First()
select new { id, n };