Sql to linq convention - linq

i have a problem to build my linq query and i need you help , the following code is what i have got so far
, it does has some errors as expected, so, this is my sql query :
*im new to linq and did searched over google.
select CAST(h.changedate as date) as 'RegDate' ,count (cast(h.changedate as date)) as 'Amount' from T_TalmidStatusHistory h
join T_talmid t on h.talmidid = t.talmidid
where t.talmidStatusID=16 and h.[statusid] != 16
and h.id =
(
select max(id) from T_TalmidStatusHistory
where T_TalmidStatusHistory.talmidid=h.talmidid and T_TalmidStatusHistory.[statusid] != 16
)
group by CAST(h.changedate as date)
and this is what i have right now in linq:
var res = from r in db.T_TalmidStatusHistories
from m in db.T_TalmidStatusHistories
join t in db.T_Talmids on r.TalmidID equals t.TalmidID
where t.TalmidStatusID == 16 && r.StatusID != 16
&& r.id == from l in db.T_TalmidStatusHistories
where m.TalmidID == r.TalmidID && m.StatusID != 16
select new{db.T_TalmidStatusHistories.OrderByDescending(tp => tp.id).FirstOrDefault().id }
group h by h.changedate as date
select new { h.changedate as date, count (cast(h.changedate as date))};
Edit:
i'm expecting to get the number of students that sign up on each date,
my error is :
Operator '==' cannot be applied to operands of type 'int' and 'System.Linq.IQueryable'
at line : r.id == from l in db.T_TalmidStatusHistories
ty.

The whole part
from l in db.T_TalmidStatusHistories ... count (cast(h.changedate as date))}
is one query which is compared to r.id by the == operator.
Change it to
...
r.id == (db.T_TalmidStatusHistories
.Where(m.TalmidID == r.TalmidID && m.StatusID != 16)
.OrderByDescending(tp => tp.id).FirstOrDefault().id)
group h by h.changedate as date
select new { h.changedate as date, count (cast(h.changedate as date))};

Related

Linq query - ON clause of inner join cannot compare two Guids

If the person you are searching is a CIA emplyee, take his CIAJobs.EmployerID, otherwise select People.ID
SELECT
case when CIAJobs.EmployeeID IS NULL then People.ID
else CIAJobs.EmployerID
end
FROM [FMO].[People] AS p
LEFT JOIN [FMO].[CIAJobs] j
ON (p.ID = j.[EmployeeID])
AND (j.[relationshipType] = '25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
where p.ID = '1b66e032-94b2-e811-96e0-f48c508e38a2' // id of person you search for
OR
j.[EmployeeID] = '1b66e032-94b2-e811-96e0-f48c508e38a2' // id of person you search for
I tried doing this in Linq:
var a = from l in People
join x in CIAJobs
on l.Id equals x.EmployeeID && x.RelationshipTypeGuid equals Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx.EmployeeID == null) ? l.EmployeeId : x.EmployerID;
var b = a.ToList();
why does the query show an error because of this chunk: && x.RelationshipTypeGuid equals Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')
If I remove this part it shows no error.
Error is: operator && cannot be applied to operands of type Guid and Guid.
Can you help me correct the Linq query please logically and syntactically? Thank you.
You don't need join for multiple conditions in this scenario. Use this
var a = from l in People
join x in CIAJobs
.Where(z=>z.RelationshipTypeGuid
.Equals(Guid.Parse('25a8d79d-377e-4108-8c92-0ef9a2e1ab63')))
on l.Id equals x.EmployeeID
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx.EmployeeID == null) ? l.EmployeeId : x.EmployerID;
var b = a.ToList();
But based on your problem statement this should do
var a = from l in People
join x in CIAJobs
on l.Id equals x.EmployeeID
into gcomplex
from xx in gcomplex.DefaultIfEmpty()
select (xx == null) ? l.EmployeeId : xx.EmployerID;
var b = a.ToList();

LINQ with Subquery and left join

I am trying to write LINQ query to generate below SQL query. I know it looks like assignment, but tried few syntax which generated wrong query.
select pm.Profile_Number,PD.Line_Abbrev,PD.Group_Code from Profile_Detail PD
INNER JOIN Profile_Master PM ON pd.profile_id = pm.profile_id
LEFT JOIN
(
SELECT Field_Abbr,Group_Code FROM vw_Group_Code
where ((US=1 AND Group_US_Obsolete <> 1) OR (CA=1 AND Group_CA_Obsolete <> 1) OR (MX=1 AND Group_MX_Obsolete <> 1))
)gcv ON PD.Line_Abbrev = gcv.Field_Abbr AND PD.Group_Code = gcv.Group_Code
WHERE PD.Profile_Id IN(42) AND gcv.Field_Abbr IS NULL
Tried version :
(from pd in _context.ProfileDetail
join pm in _context.ProfileMaster on pd.ProfileId equals pm.ProfileId
join vla in _context.VwLineAbbrvs on pd.LineAbbrev equals vla.LineAbbrev into gc
from vla in gc.DefaultIfEmpty()
where profileNumber.Contains(pd.ProfileId.ToString()) &&
((vla.IsUS && vla.USObsolete) || (vla.IsCA && !vla.CAObsolete) || (vla.IsMX && !vla.MXObsolete))
select new ObsoleteLineDetail
{
LineAbbrv = pd.LineAbbrev,
GroupCode = pd.GroupCode,
ProfileNumber = pm.ProfileNumber
}).ToList();

Any vs Where clause in LINQ

I always thought LINQ to SQL equivalent for an exists query is to use Any(). But i recently wrote a query in LINQ , which basically is trying to find if duplicate records exists in single table.
Anycontext.Contacts.Any(c => ((c.FirstName == contact.FirstName && c.LastName == contact.LastName && c.AddressLine1 == contact.AddressLine1 && c.Zip == contact.Zip)||
(!String.IsNullOrEmpty(contact.Email) && c.Email == contact.Email)))
matching criteria is simple to find contacts with same FirstName, LastName and AddressLine1 or same Email. This query times out in 30 sec(default), there are just 500K rows in this table.
Wherecontext.Contacts.Where(c => ((c.FirstName == contact.FirstName && c.LastName == contact.LastName && c.AddressLine1 == contact.AddressLine1 && c.Zip == contact.Zip)||
(!String.IsNullOrEmpty(contact.Email) && c.Email == contact.Email))).Count()>0
I was forced to use Where clause and then do count greater than 0 to find if any duplicate exists in the set. What i can not understand is, why LINQ to SQL on simple Any clause timing out.
Any explanation will be really great here.
EDIT
SQL From from LINQ Pad
ANY
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [Accounts].[Contacts] AS [t0]
WHERE ([t0].[CompanyID] = #p0) AND ((([t0].[FirstName] = #p1) AND ([t0].[LastName] = #p2) AND ([t0].[AddressLine1] = #p3) AND ([t0].[Zip] = #p4)) OR (([t0].[FirstName] = #p5) AND ([t0].[LastName] = #p6) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Accounts].[PhoneNumbers] AS [t1]
WHERE ([t1].[ContactNumber] = #p7) AND ([t1].[ContactID] = [t0].[ContactID])
))))
) THEN 1
ELSE 0
END) AS [value]
Where
SELECT [t0].[ContactID]
,[t0].[CompanyID]
,[t0].[CompanyTitle]
,[t0].[FirstName]
,[t0].[LastName]
,[t0].[AddressLine1]
,[t0].[AddressLine2]
,[t0].[City]
,[t0].[State]
,[t0].[Zip]
,[t0].[Email]
,[t0].[Salutation]
,[t0].[IsActive]
FROM [Accounts].[Contacts] AS [t0]
WHERE ([t0].[CompanyID] = #p0)
AND (
(
([t0].[FirstName] = #p1)
AND ([t0].[LastName] = #p2)
AND ([t0].[AddressLine1] = #p3)
AND ([t0].[Zip] = #p4)
)
OR (
([t0].[FirstName] = #p5)
AND ([t0].[LastName] = #p6)
AND (
EXISTS (
SELECT NULL AS [EMPTY]
FROM [Accounts].[PhoneNumbers] AS [t1]
WHERE ([t1].[ContactNumber] = #p7)
AND ([t1].[ContactID] = [t0].[ContactID])
)
)
)
)
Not completely sure if this is what you want, but you could compare, I'm guessing you wont run the test often, as it would be better to test for existence before you input the data to the DB.
If you want to find the duplicates then
var queryA = from a in db.someTable
select a.value;
foreach(var row in queryA){
Console.Write(queryA.Where(b => b == row).Count() > 1 ? row: "");
}
If you just want to test if it exist then.
var queryA = from a in db.someTable
select a.value;
var queryB = queryA;
queryB.Distinct();
Console.Write(queryB.Count() != queryA.Count() ? "Yes" : "No");

How to write lambda (linq) expression for sql?

I have an Sql statement for which I need go generate corresponding Lambda Expression (Linq).
Here is the SQL
Declare #CurrentUserId as int
Declare #CurrentDate as datetime
Set #CurrentDate = GetDate()
Set #CurrentUserId = 1
Select C.conferenceId,C.specialtyId,C.name,C.city,S.abbr as statebbbr,CTRY.name as countryname,C.startdate,C.enddate
from Conferences C
Inner join (
Select distinct SpecialtyId
from UserContent
Where UserId = #CurrentUserId and DeletedFlag = 0
) DT on C.SpecialtyId = DT.SpecialtyId
Left outer join State S on C.StateId = S.StateId
Inner join Country CTRY on C.CountryId = CTRY.CountryId
Where C.DisplayStartDate <= #CurrentDate
and C.DisplayEndDate >= #CurrentDate
and C.DeletedFlag = 0
and C.Publish = 1
Order by C.startdate ASC
What wolud be the lambda(linq) expression for this?
Assume data context is in variable context
from c in context.conferences
join ctry in context.country on c.CountryId equals ctry.CountryId
join s1 in context.State on c.StateId equals s.StateId into s2
from s in s2.DefaultIfEmpty()
where
c.DisplayStartDate <= System.DateTime.Now
&& c.DisplayEndDate >= System.DateTime.Now
&& c.DeletedFlag == 0 // or false if represented as a bool
&& c.Publish == 1 // or true if represented as a bool
&& context.UserContent.Any(
x => x.SpecialityId == c.specialityId
&& x.UserId == currentUserId
&& x.DeletedFlag == 0
// or if represented as a bool "&& !x.DeletedFlag"
)
select new {
c.ConferenceId,
c.SpecialtyId,
c.name,
c.city,
stateabbr = s.abbr,
countryname = ctry.name,
c.startdate,
c.enddate
}

Linq query Left Join condition

I'm trying to recreate the following sql query using Linq syntax, for some reason it is not working, please let me know what am I doing wrong here
My sql query:
select
cf.VisitConfigId,
cf.VisitName,
sv.VisitDate
from SubjectVisitConfig cf
left join SubjectVisit sv on cf.VisitConfigId = sv.VisitConfigId
My Linq query:
var q = from cf in ctms.SubjectVisitConfigs
join sv in ctms.SubjectVisits on cf.VisitConfigId equals
sv.VisitConfigId into JoinedVisits
from sv in JoinedVisits.DefaultIfEmpty()
where sv.SubjectId == subjectId.Value && sv.SiteId == siteId.Value
select new
{
sv.VisitId,
VisitDate = sv.VisitDate != null ? sv.VisitDate : null,
cf.VisitName
};
Thanks for your help!
You're dereferencing sv unconditionally in your select clause - but sv will be logically null for items which don't have a matching SubjectVisit. How would you expect your where clause to match any result where sv is null?
Here's one possible rewrite:
var q = from cf in ctms.SubjectVisitConfigs
join sv in ctms.SubjectVisits
.Where(x => x.SubjectId == subjectId.Value &&
x.SiteId == siteId.Value)
on cf.VisitConfigId equals sv.VisitConfigId into JoinedVisits
from sv in JoinedVisits.DefaultIfEmpty()
select new
{
VisitId = sv == null ? null : sv.VisitId,
VisitDate = sv == null ? null : sv.VisitDate,
cf.VisitName
};

Resources