Reputation: 547
I have two LINQ
queries, I use the results of the 1st LINQ
query and use a foreach loop to iterate through each element found and use it in the 2nd LINQ
query
var entries = dbo.OnDemand.Where(c => c.LOTNO == LotNo).Where(c => c.ODHisDate >= start && c.ODHisDate <= end).Where(c => c.Activity.Contains(reprinted)).OrderBy(c => c.ODHisDate);
foreach (var X in entries)
{
Barcodes.Add(X.Barcode); // Barcodes is a List<string>
}
foreach (string barcode in Barcodes)
{
var entries2 = dbo.OnDemand.Where(c => c.Barcode.Contains(barcode)).Where(c => c.ODHisDate >= start && c.ODHisDate <= end).OrderBy(c => c.ODHisDate);
// Do stuff with entries2
}
Is there a way I could execute this using a single query?
I read around, and people use JOIN
but I am not entirely sure how to use it.
Some of the expressions are common for both queries (the selected date range, and the ORDERBY
by date)
Currently this way works but I think there is a better way of doing what I am trying to achieve.
Any help would be appreciated.
EDIT 1:
Sample SQL query:
select * FROM [dbo].[OnDemand]
where barcode in
(
SELECT [Barcode]
FROM [dbo].[OnDemand]
group by barcode
having count(*) > 1
)
and odhisdate between '2017-01-11' and '2017-01-31'
and Activity like '%reprinted%'
order by ODHisDate asc, ODHisTime asc
Upvotes: 3
Views: 393
Reputation: 39326
I guess you're doing this because there are elements with the same barcode. A solution could be:
var entries = dbo.OnDemand.Where(c => c.LOTNO == LotNo
&& c.ODHisDate >= start && c.ODHisDate <= end
&& c.Activity.Contains(reprinted))
.Select(c => c.Barcode);//Don't need to orderby here
// You will get a IEnumerable<List<OnDemand>> as result of this query
var entries2 =entries.Select(barcode => dbo.OnDemand.Where(c => c.Barcode.Contains(barcode)
&& c.ODHisDate >= start && c.ODHisDate <= end)
.OrderBy(c => c.ODHisDate)
.ToList());
foreach (var list in entries2)
{
// do stuff
}
Better Idea could be filter first by the common conditions, later group by barcode and then keep those groups who have an element that meets the second where conditions
var entries = dbo.OnDemand.Where(c.ODHisDate >= start && c.ODHisDate <= end)
.GroupBy(c=>c.BarCode)
.Where(g=>g.Any(c=>c.LOTNO == LotNo && c.Activity.Contains(reprinted) ))
.Select(g=>g.OrderBy(c => c.ODHisDate).ToList());
var entries = dbo.OnDemand.Where(c.ODHisDate >= start && c.ODHisDate <= end && c.Activity.Contains(reprinted))
.GroupBy(c=>c.BarCode)
.Where(g=>g.Count()>1)
.Select(g=>g.OrderBy(c => c.ODHisDate));
Upvotes: 2
Reputation: 2605
As far as I can tell, there is no need for a JOIN
because you are querying the same table and you are not trying to do a recursive or cross-join query.
Why do you query the same table with the same parameters? You get a List
of entries back, then iterate through Barcode
values and then go back again and query the same table with the same Barcode
value.
If you want to iterate in-line, the syntax is straight forward, but I am not sure if you understand what you are doing there.
dbo.OnDemand.Where(c => c.Barcode.Contains(barcode))
.Where(c => c.ODHisDate >= start && c.ODHisDate <= end)
.OrderBy(c => c.ODHisDate)
.ForEach(c =>
{
// do stuff
}
Upvotes: 4