I've been assigned a new project at work which uses NHibernate. A query that I can easily write in sql has me totally stumped on how to do it in linq, which is how I've been told to do it.
So, here's the query:
select ts.BatchID, COUNT(distinct ts.UniqID) SurveyCount
from TeleformStaging.TeleformStaging ts
where ts.IsRescan = 0
and not exists (select bfr.BatchID
from TeleformStaging.BatchesForRescan bfr
where bfr.BatchTrack = ts.BatchID)
group by ts.BatchID
order by ts.BatchID
I believe I could get the 'group by' portion, but no idea on the subquery.
Thanks for any advice...
Maybe something like this:
var result= (
from ts in db.TeleformStaging
where ts.IsRescan == false //if is a boolean else == 0
&&
!(
from bfr in db.BatchesForRescan
select bfr.BatchTrack
).Contains(ts.BatchID)
orderby ts.BatchID
group ts by ts.BatchID into g
select new
{
BatchID=g.Key,
SurveyCount=g.Select (x =>x.UniqID).Distinct().Count()
}
);
where db is the linq data context
Edit
You could also do it with .Any(). Like this:
var result= (
from ts in db.TeleformStaging
where ts.IsRescan == false //if is a boolean else == 0
&&
!(
from bfr in db.BatchesForRescan
where ts.BatchID==bfr.BatchTrack
select bfr.BatchTrack
).Any()
orderby ts.BatchID
group ts by ts.BatchID into g
select new
{
BatchID=g.Key,
SurveyCount=g.Select (x =>x.UniqID).Distinct().Count()
}
);
Edit 1
Useful links:
Contains
Any
Simple group by
Basic LINQ Query Operations (C#)
Order by
LINQ is slightly reversed, but does offer the complexity with a few lambda expressions; how does this look:
var result = from ts in TeleformStaging.TeleformStaging
where !ts.IsRescan && !TeleformStaging.BatchesForRescan.Any(bfr => bfr.BatchID == ts.BatchID)
group ts by ts.BatchID into tsGrouped
orderby tsGrouped.Key
select new
{
BatchId = tsGrouped.Key,
SurveyCount = tsGrouped.Select(x => x.UniqID).Distinct().Count()
};
from fs in context.TeleformStaging
where !ts.IsRescan && !context.BatchesForRescan.Any(bfr=>bfr.BatchTrack == ts.BatchID)
group ts by ts.BatchID into g
select new
{
BatchID=g.Key,
SurveyCount=g.Select (x =>x.UniqID).Distinct().Count()
}
with group by
Related
I have 3 table
Tbl_City , Tbl_GroupCities , Tbl_CtrCar .
I want to convert this SQL query to LINQ or lambda expression in C#
declare #fk_group uniqueidentifier
SELECT #fk_group= FK_Group
FROM dbo.Tbl_User
WHERE UserName='meysam'
SELECT dbo.Tbl_City.ID_City, dbo.Tbl_City.Name_City,COUNT( dbo.Tbl_CtrCar.Cur_year)
FROM dbo.Tbl_City
INNER JOIN dbo.Tbl_CtrCar ON dbo.Tbl_City.ID_City = dbo.Tbl_CtrCar.FK_City
WHERE ID_City IN (SELECT FK_City
FROM dbo.Tbl_GroupCities
WHERE Active=1 AND ID_Group=#fk_group)
GROUP BY ID_City , Name_City
I try it but it's not work
var model = _TblUser.FirstOrDefault(x => x.UserName == "sampleUserName");
var q = _TblGroupCities.Where(x => x.IdGroup == model.FkGroup && x.Active == true);
var sample2 =
(from x in _TblCity
join a in _TblGroupCities on x.IdCity equals a.FkCity
where a.Active == true && a.IdGroup == model.FkGroup
select new
{
x.IdCity,
x.NameCity
}).ToList();
Please take a look here the features you have in your query are not yet implemented. GroupBy and i think also subselects will do an
SELECT * FROM TableName
And in memory it will do the group by or even for each row a new SQL query.
Better to use the RawSql method for this purpose.
But if you realy want to learn LINQ and convert your SQL take a look at LINQPad
This issue is done. I found my problem, I don't Understand use two joins and use group by in Linq
I use this linq for the solution and run
var model = _TblUser.SingleOrDefault(x => x.UserName == type.UserName);
var q = _TblGroupCities.Where(x => x.IdGroup == model.FkGroup && x.Active == true);
tblCityViewModel = new List<MohasebKhodro.ViewModels.TblCityViewModel>();
var sample2 =
(from x in _TblCity
join a in _TblGroupCities on x.IdCity equals a.FkCity
where a.Active == true && a.IdGroup == model.FkGroup
select new
{
x.IdCity,
x.NameCity
}).ToList();
foreach (var item in sample2)
{
var er = _TblCtrCar.Where(x => x.FkCity == item.IdCity).Max(x => x.CurYear);
tblCityViewModel.Add(new MohasebKhodro.ViewModels.TblCityViewModel
{
IdCity = item.IdCity,
NameCity = item.NameCity,
MaxCurrentYear = Convert.ToString(er)
});
}
I am trying to convert an SQL query that works, to LINQ equivalent.
Here is the query.
SELECT REPORT_NUMBER,
case when count(distinct STATE) > 1 then 'PENDING'
else case when max(STATE) = 'REPORTED' then 'REPORTED'
else 'PENDING' end end status,
max(REPORT_YEAR)
FROM SAMPLE
GROUP BY REPORT_NUMBER
ORDER BY max(REPORT_YEAR) DESC
So far I created LINQ query that needed a help.
var sums = from foo in db.SAMPLEs
group foo by foo.REPORT_NUMBER into groupings
orderby groupings.Key ascending
select new ReportListModel
{
ReportNbr = groupings.Key,
ReportYear = groupings.Max(g => g.REPORT_YEAR),
ReportSt = groupings.Max(g => g.STATE)
};
Using groupings.Max(g => g.STATE) gives me correct amount of records, but obviously gives me incorrect field result.
How can I create case statement as in SQL query?
You can use inline-if operator like so:
var sums = from foo in db.SAMPLEs
group foo by foo.REPORT_NUMBER into groupings
orderby groupings.Key ascending
select new ReportListModel
{
ReportNbr = groupings.Key,
ReportStatus =
groupings.Select(x => x.STATE).Distinct().Count() > 1 ?
"PENDING" : (
groupings.Max(g => g.STATE) == "REPORTED" ?
"REPORTED" : "PENDING"
)
};
I have following LINQ query. I want to be able to select Count of the record selected as well. For example, select w.EndDate, countOfRecordsSelected.
How do I go about it ?
var ConferenceOrderedByDate = (from c in participant.Conference
where c.Status == Status.Completed
&& c.EndDate.HasValue
&& c.EndDate <=Deadline
&& c.EndDate > MinimumDate
orderby c.EndDate ascending
select c.EndDate);
Thanks in advance!!
var ConferenceOrderedByDate = (from c in participant.Conference
where c.Status == Status.Completed
&& c.EndDate.HasValue
&& c.EndDate <=Deadline
&& c.EndDate > MinimumDate
orderby c.EndDate ascending
select new {
EndDate = c.Detail.EndDate,
Count = c.countOfRecordsSelected
});
this will create an anonymous type and you can access them by simply using ConferenceOrderedByDate.EndDate and ConferenceOrderedByDate.Count.
If you want the amount of records selected by the query, because I'm not sure which count you're referring to, just use
ConferenceOrderedByDate.Count()
I have realized that SQL Server is unable efficiently process some basic SQL queries, such as:
SELECT TOP (1) [t0].[Id], [t0].[L1], [t0].[L2], [t0].[Value]
FROM [Foos] AS [t0]
INNER JOIN [Lookup1] AS [t1] ON [t1].[Id] = [t0].[L2]
INNER JOIN [Lookup2] AS [t2] ON [t2].[Id] = [t0].[L1]
WHERE ([t1].[Name] = 'a') AND ([t2].[Name] = 'b')
ORDER BY [t0].[Value]
which is generated from LINQ expression:
// query 1
Foos
.Where(f => f.Lookup1.Name == "a" && f.Lookup2.Name == "b")
.OrderBy(f => f.Value)
.Take(1)
The schema definition is in question 'Index over multiple lookup tables in SQL Server'. #Hoots in the answer shows that the SQL query must look like:
SELECT TOP (1) [t0].[Id], [t0].[L1], [t0].[L2], [t0].[Value]
FROM [Foos] AS [t0]
CROSS JOIN (
SELECT TOP (1) [t1].[Id], [t2].[Id] AS [Id2]
FROM [Lookup1] AS [t1], [Lookup2] AS [t2]
WHERE ([t1].[Name] = 'a') AND ([t2].[Name] = 'b')
) AS [t3]
WHERE ([t0].[L1] = [t3].[Id]) AND ([t0].[L2] = [t3].[Id2])
ORDER BY [t0].[Value] DESC
which could be generated from the following LINQ expression:
// query 2
(from f in Foos
from l in (
from l1 in Lookup1s
from l2 in Lookup2s
where l1.Name == "a"
&& l2.Name == "b"
select new { L1 = l1.Id, L2 = l2.Id }).Take(1)
where f.L1 == l.L1 && f.L2 == l.L2
orderby f.Value descending
select f).Take(1)
My question is how to automatically rewrite the query 1 into query 2? So I could compose queries in multiple steps:
void Do()
{
var x = ListFoos("a", "b").OrderBy(f => f.Value).Take(2);
// ...
}
IQueryable<Foos> ListFoos(string l1, string l2)
{
var foos = Foos.AsQueryable();
if (l1 != null)
foos = foos.Where(f => f.Lookup1.Name == l1);
if (l2 != null)
foos = foos.Where(f => f.Lookup2.Name == l2);
return foos;
}
Has someone done that already? Is there a library simplifying the task?
Clarification:
The resulting expression of IQueryable<> is translated into SQL statement which SQL Server is unable efficiently evaluate. So I need to transform the expression into an expression which is translated into better SQL statement for SQL Server.
I think that I am not the first who has encountered this issue. LINQ is a longer time here and the SQL statements are pretty basic, so other developers might already have been solving this problem with SQL Server.
I'm not 100% certain I know what you're asking for, but if I am right, you should look at PredicateBuilder. It's very useful. Link here:
http://www.albahari.com/nutshell/predicatebuilder.aspx
It's part of LinqKit:
http://www.albahari.com/nutshell/linqkit.aspx
and here's some info on how it's used:
How does PredicateBuilder work
It will basically let you do something like this:
var predicate = PredicateBuilder.True<Foo>();
if (l1 != null)
predicate = predicate.And(f => f.Lookup1.Name == l1);
if (l2 != null)
predicate = predicate.Or(f => f.Lookup2.Name == l2);
return Foos.Where(predicate);
Note the above is from memory.. I have not tested this...so might have some typos...
Hello I have the following linq statement:
IEnumerable<TabTransaktion> allTransactions
= TabTransaktions1.Union(TabTransaktions2)
.Where(trans => trans.TabVorgang != null).
.OrderBy(tran => tran.TabVorgang.Wirkdatum)
.OrderByDescending(trans2 => trans2.TabVorgang.ID);
But I want the second order by descending when only trans2.TabVorgang.ID equals to 0. So I need a "case" in "order by clause" for LinQ. A LinQ equivalent of something like this:
SELECT BusinessEntityID, SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
GO
I would appreciate any help.
Assuming SalariedFlag is a bool (in SQL of type bit), the two ordering expressions are exclusively mutual. In other words, the main query can be separated into two disjunctive queries and the final result is the union of them:
IEnumerable<TabTransaktion> mainQuery
= TabTransaktions1.Union(TabTransaktions2)
.Where(trans => trans.TabVorgang != null);
var queryOne = mainQuery.Where(p=>p.SalariedFlag ==1)
.OrderByDescending(tran => tran.BusinessEntityID );
var queryTwo = mainQuery.Where(p=>p.SalariedFlag ==0)
.OrderBy(tran => tran.BusinessEntityID);
var finalResult = queryOne.Union(queryTwo);