Convert SQL query with inner, left, and nested select to LINQ - sql

how can convert this query to linq?
SELECT p.PostID, p.PostText, p.PublishDate, u.Name
FROM AspNetUsers u INNER JOIN Posts p ON u.Id = p.PostUserID LEFT JOIN Reposts r ON p.PostID = r.PostID
WHERE p.PostUserID = 'id'
OR p.PostUserID IN ( SELECT FollowingUserID FROM Friends WHERE FollowerUserID = 'id' AND isUnfollow = 0)
OR p.PostID in (SELECT PostID FROM Reposts WHERE RepostUserID = 'id' OR RepostUserID IN ( SELECT FollowingUserID FROM Friends WHERE FollowerUserID = 'id' AND isUnfollow = 0))
ORDER BY p.PostUserID

Does this work?
var results = from u in AspNetUsers
join p in Posts on u.Id equals p.PostUserID
join r in Reposts on p.PostId equals r.PostId into records
from record in records.DefaultIfEmpty()
where p.PostUserID == "id"
|| (from friend in Friends
where friend.FollowerUserID == "id"
&& friend.isUnfollow == 0
select friend.FollowingUserID
).Contains(p.PostUserID)
|| (from r2 in Reposts
where r2.RepostUserID == "id"
|| (from friend2 in Friends
where friend2.FollowerUserID == "id"
&& friend2.isUnfollow == 0
select friend2.FollowingUserID
).Contains(r2.RepostUserID)
select r2.PostID
).Contains(p.PostID)
orderby p.PostUserID ascending
select p.PostID, p.PostText, p.PublishDate, u.Name;

Related

where clause subquery in LINQ

I am trying to convert my SQL syntax to the LINQ query , And I have a problem with a subquery.
I want to select max date-time with an Id in a table as a subquery for another select command but I don't know what's right or wrong with this below code.
what I have in Sql
select ap.* ,aph.Lat as 'personLat',aph.Lng as 'personLng',l.cityId,l.Lat as 'LifecenterLat',l.lng as 'LifecenterLng',l.Id as 'LifeCenterId'
from Applicant ap
inner join ApplicantAddressHistory aph on ap.Id = aph.ApplicantId
inner join LifePlusCenter l on aph.CityId = l.CityId
Where ap.FamilyRoleTypeId = '82e26080-fda6-4396-946c-40d0e267f1f3' and aph.CreatedDate in (select max(CreatedDate) from ApplicantAddressHistory
where ApplicantAddressHistory.ApplicantId = ap.Id)
order by ap.NationalityCode
And what I have tried in linq
var innerJoinMultipleTables = from app in db.Applicant.Where(x => x.FamilyRoleTypeId == Guid.Parse("82e26080-fda6-4396-946c-40d0e267f1f3"))
join aph in db.ApplicantAddressHistory on app.Id equals aph.ApplicantId
where aph.CreatedDate == db.ApplicantAddressHistory.Max(x => x.CreatedDate && x.Id=aph.Id)
join l in db.LifePlusCenter on aph.CityId equals l.CityId
let centerLat = l.Lat
let centerLng = l.Lng
orderby app.NationalityCode
select new { app, aph.Lat, aph.Lng, l.CityId, l.Branch, centerLat, centerLng };
without this below line of code ,my linq works correctly.
where aph.CreatedDate == db.ApplicantAddressHistory.Max(x => x.CreatedDate && x.Id=aph.Id)
I need something like this below code in Linq as a subquery
select max(CreatedDate) from ApplicantAddressHistory where ApplicantAddressHistory.ApplicantId = '9836CEC4-EDCB-492C-9899-DF4279210CD2'
I finally tried this and it workd but dont know its correct way or not?!
var innerJoinMultipleTables = from app in db.Applicant.Where(x => x.FamilyRoleTypeId == Guid.Parse("82e26080-fda6-4396-946c-40d0e267f1f3"))
join aph in db.ApplicantAddressHistory on app.Id equals aph.ApplicantId
let rept_max = (from c in db.ApplicantAddressHistory
where c.Id == app.Id
select c.CreatedDate).Max()
where aph.CreatedDate == rept_max
join l in db.LifePlusCenter on aph.CityId equals l.CityId
let centerLat = l.Lat
let centerLng = l.Lng
orderby app.NationalityCode
select new { app, aph.Lat, aph.Lng, l.CityId, l.Branch, centerLat, centerLng };
Am not sure how it works in Linq, but you can modify your query like below to get latest details as per CreatedDate for each ApplicantId.
select ap.* ,aph.Lat as 'personLat',aph.Lng as 'personLng',l.cityId,l.Lat as 'LifecenterLat',l.lng as 'LifecenterLng',l.Id as 'LifeCenterId'
from Applicant ap
inner join
(select *
from
(select *,row_number() over(partition by ApplicantId order by CreatedDate desc) rw
from ApplicantAddressHistory
) p
where p.rw=1
) aph
on ap.Id = aph.ApplicantId
inner join LifePlusCenter l
on aph.CityId = l.CityId
Where ap.FamilyRoleTypeId = '82e26080-fda6-4396-946c-40d0e267f1f3'
/*
and aph.CreatedDate in (
select max(CreatedDate) from ApplicantAddressHistory
where ApplicantAddressHistory.ApplicantId = ap.Id
)
*/
order by ap.NationalityCode
Finally I came up to :
var z = from app in db.Applicant
join aph in db.ApplicantAddressHistory on app.Id equals aph.ApplicantId
join l in db.LifePlusCenter on aph.CityId equals l.CityId
let createDate = app.ApplicantAddressHistory.Max(c => c.CreatedDate)
where createDate.HasValue && aph.CreatedDate == createDate
&& app.FamilyRoleTypeId == Guid.Parse("82e26080-fda6-4396-946c-40d0e267f1f3")
let personLat = aph.Lat
let personLng = aph.Lng
let centerId = l.Id
let LifecenterLat = l.Lat
let LifecenterLng = l.Lng
orderby app.NationalityCode
select new { app, aph, l, app.Id, l.CityId, centerId, personLat, personLng, LifecenterLat, LifecenterLng };

How can I perform a left join and exclude results that match a subquery in LINQ?

Need to convert this sql query to LINQ
SELECT *
FROM
parcels p
LEFT JOIN leases l ON p.parcels_pk = l.parcels_fk
WHERE
l.parcels_fk IS NULL
AND p.parcels_pk NOT IN (SELECT parcels_fk FROM application_parcels)
ORDER BY parcel
tried this:
var qry = from p in db.Parcels
join l in db.Leases on p.Id equals l.pk_parcel
where l.pk_parcel == null
&& !(from ap in db.ApplicationParcels
select ap.ParcelId).Contains(p.Id)
orderby p.Name
// SELECT * FROM parcels
var result = from p in parcels
// LEFT JOIN leases ON p.parcels_pk = l.parcels_fk
join llj in leases on p.parcels_pk equals llj.parcels_fk into lj
from l in lj.DefaultIfEmpty()
// WHERE l.parcels_fk IS NULL
where l.parcels_fk == null
// AND p.parcels_pk NOT IN (...)
&& !application_parcels.Any(x => x.parcels_fk == p.parcels_pk)
// ORDER BY [p.]parcel
order by p.parcel
select new { parcel = p, lease = l };
Assuming i have your schema correct.
But in the future:
First supply what you've tried (show an effort).
Have a look at LINQPad, it's very helpful.

Converting SQL to LINQ to Entity

I am trying to convert the following SQL, not written by myself, into a Linq to Entity query.
select
u.user_Id,
u.forename,
u.surname,
u.client_code,
u.user_name,
u.password,
u.email,
u.gender,
u.Report_Date,
u.EmailDate,
count(ut.test_Id) as testcount,
sum(cast(isnull(ut.completed,0) as int)) as Testcompleted,
u.job_function,
lu.lookupvalue
from
users u inner join user_Relationship ur
on u.user_Id= ur.child_Id
left join user_tests ut
on ut.user_id=u.user_id
inner join lookup lu on u.first_languageId = lu.lookupid
where ur.parent_Id = #Parent_Id
group by
u.user_Id, u.forename,u.surname,u.client_code,u.user_name, u.password,
u.email, u.gender, u.first_languageId, u.Report_Date,u.EmailDate,
u.job_function, lu.lookupvalue
So far, I have been able to do this:
from u in db.Users
join ur in db.User_Relationship on u.User_ID equals ur.Child_ID
join ut in db.User_Tests on u.User_ID equals ut.User_ID into ps
from ut in ps.DefaultIfEmpty()
join lu in db.Lookups on u.First_LanguageID equals lu.LookupID
where ur.Parent_ID == 45875
select new UserViewModel
{
User_ID = u.User_ID,
Forename = u.Forename,
Surname = u.Surname,
Client_Code = u.Client_Code,
User_Name = u.User_Name,
Password = u.Password,
Email = u.Email,
Gender = u.Gender,
Report_Date = u.Report_date,
Email_Date = u.EmailDate,
//Insert Test_Count and Test_Completed
Job_Function = u.Job_Function,
Lookup_Value = lu.LookupValue
});
How do I replicate the Group and Count() function of SQL?
Well tweak around this solution coz currently i dont have .Net environment for testing this solution, but you'll sure get how grouping is done in linq.
from u in db.Users
join ur in db.User_Relationship on u.User_ID equals ur.Child_ID
join ut in db.User_Tests on u.User_ID equals ut.User_ID into ps
from ut in ps.DefaultIfEmpty()
join lu in db.Lookups on u.First_LanguageID equals lu.LookupID
where ur.Parent_ID == 45875 group new{u,lu} by new {u.User_ID,u.Forename,
u.Surname,u.Client_Code,
u.User_Name,u.Password,
u.Email,u.Gender,u.Report_date,
u.EmailDate,u.Job_Function,
lu.LookupValue} into g
let Test_Count = ps.Count(x=>x.test_Id)
let Test_Completed = ps.Sum(x=>x.completed)
select new UserViewModel
{
User_ID = g.Key.User_ID,
Forename = g.Key.Forename,
Surname = g.Key.Surname,
Client_Code = g.Key.Client_Code,
User_Name = g.Key.User_Name,
Password = g.Key.Password,
Email = g.Key.Email,
Gender = g.Key.Gender,
Report_Date = g.Key.Report_date,
Email_Date = g.Key.EmailDate,
Test_Count = Test_Count,
Test_Completed = Test_Completed,
Job_Function = u.Job_Function,
Lookup_Value = lu.LookupValue
});

INNER JOIN LEFT JOIN in LINQ to SQL

How to convert INNER JOIN and LEFT JOIN in the following SQL query to LINQ to SQL? Thanks!
SELECT transactions.postdate,
transactions.clientkey AS TransClientKey,
transactions.type AS TransType,
clients.clientno,
Isnull(clients.nostmt, 0) AS CliNoStmt,
Isnull(aging.nostmt, 0) AS AgeNoStmt,
pmtchecks.*
FROM ((pmtchecks
INNER JOIN transactions
ON pmtchecks.transkey = transactions.transkey)
INNER JOIN clients
ON transactions.clientkey = clients.clientkey)
LEFT JOIN aging
ON ( transactions.clientkey = aging.clientkey )
AND ( pmtchecks.debtorkey = aging.debtorkey )
WHERE ( pmtchecks.debtorkey = 36927 )
AND ( transactions.status = 0 )
AND ( transactions.postdate <= '31-May-2012' )
AND ( ( transactions.postdate >= '01-May-2012' )
OR ( clients.clientno = 'UNKNOWN' ) )
ORDER BY pmtchecks.checkdate,
pmtchecks.checkno
Hi this is kind of dummy code i cnt say its exactly right but the idea will be exactly same to get the result
var anonymousType= (from pm in pmtchecks
join tr in transactions
on pm.transkey equals tr.transkey //INNERJOIN
join cl in clients
on tr.clientKey equals cl.clientKey
join ag in aging
on pm.debtorkey equals ag.debtorKey into ljoin //Left Join
from lj in ljoin.DefaultOrEmpty()
where pm.debortkey==36927 && tr.status==0 && tr.postdate<="31-May-2012" && tr.postdate>="01-May-2012" //u will have to change this to date format first
Select new {PostDate=tr.postdate, TransClientKey=tr.clientkey,TransType=tr.type,ClientNo=cl.clientno,CliNoStmt=cl.nomst ?? 0,AgeNoStmt=ag.nomst ??0,Pmtchecks=pm } //Anonymous type from this you can extract the values and fill to your custom type
).OrderBy(o=>o.Pmtchecks.checkdate).OrderBy(o=>o.Pmtchecks.checkno).ToList();
Hope this will help.
LINQ Query Samples
EDITED
var pmtchecks = from p in urcontext.pmtchecks
join t in urcontext.transactions on p.transkey equals t.transkey
join a in urcontext.aging on t.clientkey equals a.clientkey into details
from d in details.Where( a => ( a.debtorkey == p.debtorkey)).DefaultIfEmpty()
where (p.debtorkey == 36927 && t.status == 0 && t.postdate <= '31-May-2012'
&& (t.postdate >= '01-May-2012' || c.clientno == 'UNKNOWN' ))
orderby p.checkdate, p.checkno
select new
{
t.postdate,
t.clientkey,
// TransClientKey = t.clientkey, //only works if TransClientKey is property
t.type ,
//TransTypet = t.type ,//property
c.clientno,
c.nostmt,
//CliNoStmt = c.nostmt ?? 0,//property
a.nostmt//,
//AgeNoStmt = nostmt ?? 0,//property
//p. ... //follow above for p columns
};

Complex SQL to LINQ conversion with subquery

I am trying to convert this expression into LINQ from SQL, but a bit too difficult for me, maybe you can help me with this!
SELECT TOP (2) RecipeID, UserID, Name, Servings, PreparationTime, TotalTime, DifficultyLevelID, CuisineID, DishID, MainIngredientID, PriceLevelID, FlavourID, Instructions,
Notes, Thumbnail, VideoLink
FROM dbo.Recipes
WHERE (RecipeID NOT IN
(SELECT DISTINCT Recipes_1.RecipeID
FROM dbo.Allergies INNER JOIN
dbo.UsersAllergies ON dbo.Allergies.AllergyID = dbo.UsersAllergies.AllergyID INNER JOIN
dbo.IngredientsAllergies ON dbo.Allergies.AllergyID = dbo.IngredientsAllergies.AllergyID INNER JOIN
dbo.Ingredients ON dbo.IngredientsAllergies.IngredientID = dbo.Ingredients.IngredientID INNER JOIN
dbo.RecipesIngredients ON dbo.Ingredients.IngredientID = dbo.RecipesIngredients.IngredientID INNER JOIN
dbo.Recipes AS Recipes_1 ON dbo.RecipesIngredients.RecipeID = Recipes_1.RecipeID INNER JOIN
dbo.Users ON dbo.UsersAllergies.UserID = dbo.Users.UserID INNER JOIN
dbo.AllergyFactors ON dbo.IngredientsAllergies.AllergyFactorID = dbo.AllergyFactors.AllergyFactorID
WHERE (dbo.Users.UserID = 3) AND (dbo.AllergyFactors.AllergyFactorID < 3)))
It would be easier to help you if you showed us what you have already tried, but a Linq expression like this should give you the same result set
var query = (from rec in context.Recipes
where !(from al in context.Allergies
from ua in context.UsersAllergies.Where(x => al.AllergyID == x.AllergyID)
from ia in context.IngredientsAllergies.Where(x => al.AllergyID == x.AllergyID)
from in in context.Ingredients.Where(x => ia.IngredientID == x.IngredientID)
from ri in context.RecipesIngredients.Where(x => in.IngredientID == x.IngredientID)
from re in context.Recipes.Where(x => ri.RecipeID == x.RecipeID)
from us in context.Users.Where(x => ua.UserID == x.UserID)
from af in context.AllergyFactors.Where(x => ia.AllergyFactorID == x.AllergyFactorID)
where us.UserID == 3 && af.AllergyFactorID < 3
select re.RecipeID)
.Distinct()
.Contains(rec.RecipeID)
select new
{
rec.RecipeID,
rec.UserID,
rec.Name,
rec.Servings,
rec.PreparationTime,
rec.TotalTime,
rec.DifficultyLevelID,
rec.CuisineID,
rec.DishID,
rec.MainIngredientID,
rec.PriceLevelID,
rec.FlavourID,
rec.Instructions,
rec.Notes,
rec.Thumbnail,
rec.VideoLink
}).Take(2);