I have the following TSQL
SELECT COUNT(M.MuseumID) as [ACTIVECARDHOLDERS]
FROM Museum AS M
WHERE M.MuseumID IN
(SELECT MAX(X.MuseumID) AS MuseumID
FROM (SELECT BioStation.[MuseumID]
,BioStation.[PersonID]
,ISNULL(M.ISCARDINVALIDATED,0) AS [ISCARDINVALIDATED]
FROM Museum AS M
INNER JOIN BioStation ON BioStation.MuseumID = Museum.MuseumID
WHERE M.CASESTATE=7 AND M.CASESTATUS=6) AS X
GROUP BY X.PERSONID)
AND ISNULL(M.ISCARDINVALIDATED,0)=0;
I'm trying to convert to linq in C#, starting with the inner most query, however I'm unsure how to nest them in linq with group\max. This is what I have so far that's bug free:
var query = (from m in dbContext.Museum
join b in dbContext.BioStation on m.MuseumID equals b.MuseumID
where m.CaseState == 7 && m.CaseStatus == 6
select new {b.MuseumID, b.PersonID, IsCardInvalidated = (m.IsCardInvalidated == null ? false : m.IsCardInvalidated) }).AsQueryable();
Any help with the translation would be appreciated, thanks.
Related
I would like to write the following SQL query with LINQ syntax to understand the fundamentals of LINQ queries.
SELECT q.*, qpph.*
FROM [Questions] AS q
LEFT OUTER JOIN [QuestionPoolPickHandles] AS qpph
ON qpph.QuestionId = q.Id AND qpph.PickerId = 100
WHERE qpph.Id IS NULL;
How can I apply left outer join and a condition in its ON clause at the same time using LINQ syntax? From my readings, it seems it is likely to be not possible.
Here's what I've tried so far.
var result = from q in context.Questions
join qpph in context.PoolPickHandles
on q.Id equals qpph.PickerId into Handles // notice the 'qpph.PickerId = 100' is absent
from m in Handles.DefaultIfEmpty()
where m == null
select q;
Any further elaboration will be appreciated.
With the help of the comments on the question, I've figured out writing the query using LINQ syntax.
from q in context.Questions
join qpph in context.PoolPickHandles
on new { questionId = q.Id, pickerId = user.Id }
equals new { questionId = qpph.QuestionId, pickerId = qpph.PickerId }
into Handles
from m in Handles.DefaultIfEmpty()
where m == null
select q;
Need some help in writing LINQ from the following SQL.
The main problem is double grouping.
I'm stacked in the second grouping
group by s.[e-year], s.[e-month]
Don't know how to implement.
Thanks a lot.
select s.[e-year], s.[e-month], count(s.projectid) 'projects entranced',
---------------------------------------------
(select count(subquery.CustomerTypeID) from
(select count(ap.ProjectID) as 'count', c.CustomerTypeID FROM Logging_ProjectsEntrances] pe
inner join users u on pe.userid = u.userid
inner join Companies c on u.CompanyId = c.CompanyID
inner join AssignedProjects up on pe.ProjectID = up.ProjectID
inner join Projects p on up.ProjectID = p.ProjectID
where ap.ProductID = 1 and year(pe.EntranceDate) = s.[e-year] and MONTH(pe.entrancedate) = s.[e-month] and c.CustomerTypeID = 2
group by ap.ProjectID, c.CustomerTypeID) subquery
group by subquery.CustomerTypeID
)
--------------------------------------------
from
(
select YEAR(pe.EntranceDate) as 'e-year', MONTH(pe.EntranceDate) as 'e-month', up.ProjectID as 'projectid'
FROM Logging_ProjectsEntrances pe
inner join AssignedProjects ap on pe.ProjectID = ap.ProjectID
inner join Projects p on ap.ProjectID = p.ProjectID
where ap.ProductID = 1
group by year(pe.EntranceDate), month(pe.EntranceDate), ap.ProjectID
) as s
group by s.[e-year], s.[e-month]
order by s.[e-year] desc , s.[e-month] desc
For translating SQL to LINQ query comprehension:
Translate FROM subselects as separately declared variables.
Translate each clause in LINQ clause order, translating monadic operators (DISTINCT, TOP, etc) into functions applied to the whole LINQ query.
Use table aliases as range variables. Use column aliases as anonymous type field names.
Use anonymous types (new { ... }) for multiple columns.
Left Join is simulated by using a into join_variable and doing another from from the join variable followed by .DefaultIfEmpty().
Replace COALESCE with the conditional operator and a null test.
Translate IN to .Contains() and NOT IN to !...Contains()
SELECT * must be replaced with select range_variable or for joins, an anonymous object containing all the range variables.
SELECT fields must be replaced with select new { ... } creating an anonymous object with all the desired fields or expressions.
Proper FULL OUTER JOIN must be handled with an extension method.
Note: Your SQL query is using a SQL trick (SELECT x ... GROUP BY x) to perform the equivalent of a DISTINCT, which should be used as it expresses the intent more clearly.
So, for your SQL query:
var subq = (from pe in projectsEntrances
join ap in assignedProjects on pe.ProjectID equals ap.ProjectID
join p in projects on ap.ProjectID equals p.ProjectID
where ap.ProductID == 1
select new { e_year = pe.EntranceDate.Year, e_month = pe.EntranceDate.Month, ap.ProjectID }).Distinct();
var ans = from s in subq
group s by new { s.e_year, s.e_month } into sg
orderby sg.Key.e_year descending, sg.Key.e_month descending
select new { sg.Key.e_year, sg.Key.e_month, ProjectsEntranced = sg.Count() };
We need to convert following query to Entity framework syntax based query but not fond any alternative for '<>' condition:
Query:
select (FirstName+' '+LastName) AS Name ,WorksNumber from [TSHumanResource]
join [TSUserProfile] on [TSUserProfile].[TSPersonID] = [TSHumanResource].[TSPersonID]
join [TSPerson] on [TSPerson].[TSPersonID] = [TSHumanResource].[TSPersonID]
where [TSUserProfile].[TSUserStatusID] = 1
and [EmployeeReference] <> ' ' and [MMSUserID] is not null order by [WorksNumber] asc
Here's what I was tring:
(from HR in oDB.TSHumanResources
join UP in oDB.TSUserProfiles on HR.TSPersonID equals UP.TSPersonID
join P in oDB.TSPersons on HR.TSPersonID equals P.TSPersonID
where UP.TSUserStatusID == 1 && HR.EmployeeReference <>
select new
{
ID = e.TSPersonID ,
ID = e.TID,
}).Take(10);
The SQL Server operator <> means not equal. In c#, the not equal operator is written like this: !=.
You have another problem in your linq query - you are currently doing an inner join instead of a left join.
A left join in LINQ is a bit cumbersome comparing to a left join in SQL - it has to go through a group join first. Your query should look more like this:
from hr in TSHumanResource
join up in TSUserProfile on hr.TSPersonID equals up.TSPersonID into upgroup
from upg in upgroup.DefaultIfEmpty()
join p in TSPerson on upg.TSPersonID equals p.TSPersonID into pgroup
from puphr in pgroup.DefaultIfEmpty()
where up.TSUserStatusID = 1
&& HR.EmployeeReference != " " // Assuming you want it different than a single space
// Other conditions here - I don't know where MMSUserID belongs to
order by hr.WorksNumber // just guessing here - I don't know if it's from hr
Is there a way to accurately convert the following SQL query to LINQ
SELECT * FROM T1
WHERE ColumnA IN (
SELECT FkColumnA FROM T2
WHERE FkColumnB IN (
SELECT ColumnB FROM T3
WHERE FkColumnC IN (
SELECT ColumnC FROM T4
WHERE FkColumnD = 1)) AND FkColumnE is null AND ColumnF = 0)
Also, does anyone know of any documentation wherein any logic or guideline to convert SQL queries to LINQ is laid out?
EDIT 1:
The equivalent for the above using JOINS would be as below:
select * from T1 a
inner join T2 b on a.FKColumnA = b.ColumnA
inner join T3 c on c.ColumnB = b.FkColumnB
inner join T4 d on d.ColumnC = c.FkColumnC
where a.FkColumnD is null and a.ColumnE = 0
and d.ColumnC = 1
and it's equivalent LINQ query would be
var linq = from q in context.T1
join r in context.T2
on q.FKColumnA equals r.ColumnA
join s in context.T3
on r.FkColumnB equals s.ColumnB
join t in context.T4
on s.FkColumnC equals t.ColumnC
where q.FkColumnD != null && q.ColumnE == false && t.ColumnC == 56816
select q.FkColumnF;
But using JOINS looked to be a bit more simpler and better in LINQ. Thus the question is for my knowledge purpose only.
Translating your query literally, we get the following LINQ statement:
var results = table1.Where(t1 => table2.Where(
t2 =>
table3.Where(
t3 =>
table4.Where(t4 => t4.FkColumnD == 1)
.Select(t4 => t4.ColumnC)
.Contains(t3.FkColumnC))
.Select(t3 => t3.ColumnB)
.Contains(t2.FkColumnB) && !t2.FkColumnE.HasValue && t2.ColumnF == 0)
.Select(t2 => t2.FkColumnA)
.Contains(t1.ColumnA));
This results in an IEnumerable<T1> which you can use as required.
As far as I know there is no "documentation" on converting syntax, this, as a developer, is your job. However, I personally find LINQPad very useful when constructing LINQ statements.
Can someone please help me convert this query to LINQ as I am new to using Linq which will then be used for google chart information.
Select Question.SubSectionName, SUM(Answers.RatingAnswer) AS Ratings
FROM Question,Answers,Response,Section
Where Answers.QuestionID = Question.QuestionID
AND Answers.ResponseID = Response.ResponseID
AND Question.SectionID=Section.SectionID
AND Section.SectionID = 2
AND Response.ResponseID = #0
AND Question.SubSectionName IS NOT Null
GROUP BY Question.SubSectionName;
What I've got so far :
var submitted = (from ans in db.Answers join ques in db.Questions on
ans.QuestionID equals ques.QuestionID
join resp in db.Responses on ans.ResponseID equals resp.ResponseID
join sec in db.Sections on ques.SectionID equals sec.SectionID
where sec.SectionID == 2 && resp.ResponseID == model.ResponseID
&& ques.SubSectionName!= null
select ques.SubSectionName && ans.RatingAnswer)
Thanks for any help.
Building on your comment this should output a grouping of sums of RatingAnswers:
var submitted =
(from ans in db.Answers
join ques in db.Questions on ans.QuestionId equals ques.QuestionId
join resp in db.Responses on ans.ResponseId equals resp.ResponseId
join sec in db.Sections on ques.SectionId equals sec.SectionId
where sec.SectionId == 2 && resp.ResponseId == model.ResponseID && ques.SubSectionName != null
select new { SubSectionName = ques.SubSectionName, RatingAnswer = ans.RatingAnswer })
.GroupBy(a => a.SubSectionName)
.Select(a => new { SectionName = a.Key, Sum = a.Sum(s => s.RatingAnswer) });
There may be a more efficient way of writing this.
I would also point out that to me the data structure seems flawed. That is, it seems either normalized incompletely or improperly. That's certainly for you to work out on your own.
Linqer helps you to convert SQL to LINQ.
If you want to get better in LINQ, I recommend using LINQPad. However, LINQPad can't convert from SQL to LINQ but from LINQ to SQL.
try this-
from q in Question
join a in Answers on q.QuestionID equals a.QuestionID
join r in Response on r.ResponseID equals a.ResponseID
join s in Section on s.SectionID equals q.SectionID
where s.SectionID= 2 and r.ResponseID= #0 and q.SubSectionName!=null
Group by q.SubSectionName