I am new in LINQ queries
and I need help to convert my sample SQL query to LINQ lambda query
select * from GRecommendations
inner join GSections
on GRecommendations.GSectionId = GSections.Id
where GSections.GaId = 646
There are two different methods you can use when GRecommendations is a collection.
var arrResult = //UNTESTED
GRecommendations
.Join(GSections.Where(sec => sec.GaId.Equals(646)),
rec => rec.GeSectionId,
sec => sec.Id,
(REC, SEC) => new { /*put here what you want selected*/ }
); //
or
var arrResult =
(
from rec in GRecommendations
join rec in GSections.Where(s => s.GaId.Equals(646)) on rec.GSectionId equals sec.GaId
select new {/*rec.something*/, /*sec.something*/}
);
Related
I am new to linq to entities. I am trying to do a not in statement and when i run it i am getting noting back. But if i run the SQL equivalent i get data back.
The SQL statement that i am trying to replicate is
SELECT * FROM [SCRAPREASON] WHERE [CODE] NOT IN (SELECT [CODE] FROM [QUALITYALERTRULE]) ORDER BY [CODE]
The Linq i have at the moment is
var DefectCode = PumaOEEEntities.ScrapReasons
.Where(x => !PumaOEEEntities.QualityAlertRules.Any(y => y.Code != x.Code))
.Select(x => new { GroupID = x.Code}).ToList();
Can anyone see what i am doing wrong?
You should compare codes for equality (== instead of !=):
var reasons = PumaOEEEntities.ScrapReasons
.Where(x => !PumaOEEEntities.QualityAlertRules.Any(y => y.Code == x.Code))
.OrderBy(x => x.Code)
.ToList();
Generated SQL will look like:
SELECT
[Extent1].[Code] AS [Code],
// Other columns
FROM [dbo].[ScrapReasons] AS [Extent1]
WHERE NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[QualityAlertRules] AS [Extent2]
WHERE [Extent2].[Code] = [Extent1].[Code]
)
ORDER BY [Extent1].[Code] ASC
You can try Except like this
var DefectCode = PumaOEEEntities.ScrapReasons.Select(x=>x.Code)
.Except(PumaOEEEntities.QualityAlertRules.Select(y=>y.Code)).ToList();
I cant get the fallowing request working in Mono:
Without joins it would work.
when I only select t1 it also works, but I cant select something from both tables.
I think I want a left join, where I always have entries in t1 and IF the NameOfFile matches FileName then I want to have the tables joined.
Extra Question: When is my query executed? When I run the foreach loop?
var result = (
from t1 in db.Table1
join t2 in db.Table2 on t1.FileName equals t2.NameOfFile
into joinDep
from t3 in joinDep.DefaultIfEmpty ()
select new
{
Time = t1.WriteTime,
Name = t2.NameOfFile
}
)
.OrderByDescending (c => c.Time.Date)
.Take (10);
foreach (var entry in result)
{
Console.WriteLine (entry.Name );
}
Use this:
var query = from t1 in db.Table1
join t2 in db.Table2 on t1.FileName equals t2.NameOfFile into gj
from joinDep in gj.DefaultIfEmpty ()
select new
{
Time = t1.WriteTime,
Name = joinDep.NameOfFile
};
var result = query.OrderByDescending (c => c.Time.Date)
.Take (10);
Yes. Take uses deferred execution.
I'm trying to create a Linq query for EF that joins on 2 values from an inner select. Underneath you will find the SQL query that does the trick, things are much more tricky when trying to do so in Linq.
I use POCO object and would like the query to return the List and not an anonymous type. Is this possible with Linq to EF?
SELECT s1.*
FROM [Statistics] s1
INNER JOIN
(
SELECT MAX(CreateDate) as createdate
FROM [Statistics]
GROUP BY UserId
) s2
ON s1.UserId = s2.[UserId] and s1.CreateDate = s2.createdate
ORDER BY s1.Balance desc
You can do this with a Where or a Join.
from s1 in Statistics
join s2 in (from s in Statistics group s by s.UserId into g
select new { UserId = g.Key, CreateDate = g.Max (s => s.CreateDate) })
on new { s1.UserId, s1.CreateDate } equals new { s2.UserId, s2.CreateDate }
orderby s1.Balance descending
select s1;
Or,
from s1 in Statistics
from s2 in (from s in Statistics group s by s.UserId into g
select new { UserId = g.Key, CreateDate = g.Max (s => s.CreateDate) })
where s1.UserId == s2.UserId && s1.CreateDate == s2.CreateDate
orderby s1.Balance descending
select s1;
I am trying to get fields from one table and max(expirationDate) from another table. This is my original linq query:
tanks = (From t In db.Table1 _
Where t.CompanyID = txtCompanyID.Text.Trim() _
Join d In db.Table2 On t.TankID Equals d.TankID
Order By d.ExpireDate Descending
Select t).ToList
that brings back multiple expireDates, I only want the max(expireDate) for each record
The following sql query works, I just need to put it into a linq query
select t1.*,
(Select MAX(Table2.ExpireDate)
from Table2 as t2
where t2.TankID = t1.TankID)
as max_expire_date
from Table1 as t1
where t1.CompanyID = '5467'
order by t1.CargoTankID
Does anybody know how to get this into linq? Thanks
tanks = db.Table1.Where( t => t.CompanyId == txtCompanyID.Text.Trim() )
.Join( db.Table2, t1 => t1.TankID, t2 => t2.TankID, (t1,t2) => new { Company = t1, t2.ExpireDate } )
.GroupBy( t => t.Company, (c,e) => new { Company = c Expiration = e.Max( x => x.ExpireDate ) } )
.ToList();
Best guess at VB
Dim tanks = db.Table1.Where( Function(t) t.CompanyId == txtCompanyID.Text.Trim() ) _
.Join( db.Table2, Function(t1) t1.TankID, Function(t2) t2.TankID, Function(t1,t2) New Thing With { .Company = t1, .ExpireDate = t2.ExpireDate } ) _
.GroupBy( Function(t) t.Company, Function(c,e) New Thing With { .Company = c, .Expiration = e.Max( Function(x) x.ExpireDate ) } ) _
.ToList()
Using LinqToSql, I need to return a single (L) for the most recent modDate in a join table (CL).
Tables:
L (Lid, meta1, meta2, ...)
CL (Cid, Lid, ModDate)
Here is sql that produces the expected result
SELECT l.*
FROM L l
INNER JOIN (
SELECT TOP 1 cl.Lid, MAX(cl.ModDate) as ModDate
FROM CL cl
INNER JOIN L l ON cl.Lid = l.Lid AND l.meta1 = 5
GROUP BY cl.Lid
ORDER BY MAX(cl.ModDate) DESC
) As m ON l.Lid = m.Lid
Simple enough. The subquery projects us to the ids. The query fetches those records with matching ids.
var subquery = db.L
.Where(L => L.meta1 = 5)
.SelectMany(L => L.CLs)
.GroupBy(CL => CL.Lid)
.OrderByDescending(g => g.Max(CL => CL.ModDate))
.Select(g => g.Key)
.Take(1)
var query = db.L
.Where(L => subquery.Any(id => L.Lid == id))
Reflecting on this further, you can get away from the subquery:
var query = db.L
.Where(L => L.meta1 = 5)
.SelectMany(L => L.CLs)
.GroupBy(CL => CL.Lid)
.OrderByDescending(g => g.Max(CL => CL.ModDate))
.Select(g => g.First().L);
As your provided query, I can interpret into this Linq.
var query = from l in Context.L
join m in (from cl in Context.CL
join l in Context.L on cl.Lid equals l.Lid
where l.meta1 == 5
group new { l.Lid, cl.ModDate } by cl.Lid into grp
select new { Lid = grp.Key, ModDate = grp.Max(g => g.ModDate) } into grp
order by grp.ModDate descending
select grp).Take(1) on l.Lid equals m.Lid
select l;
My SQL-fu isn't fabulous and it's before my first coffee, so I assume "l" in the outer query ends up being a completely different "l" to the one in the subquery?
I think this will do it, but you'll have to try to be sure :) It'll be well worth checking what the generated SQL looks like. If you didn't mind it executing as two queries, of course, it would be somewhat simpler.
// Can't do the "Take(1)" here or it will be executed separately
var subquery = from cl in context.CL
join l in context.L on cl.Lid = l.Lid
where l.meta1 = 5 // could put this in join clause
group cl.ModDate by cl.lid into grouped
order by grouped.Max() descending
select grouped.Key;
// But can take the first result of the join
// This may be simpler using dot notation instead of a query expression
var query = (from l in context.L
join lid in subquery
select l).Take(1);
(EDIT: I wasn't taking the max ModDate before. Doh. Also simplified grouping by using the ID as the key (which it was already) so we only need the ModDate as the group values.)