I have a table with the following relevant columns:
- Machine [Key]
- Sample
- Experiment
- DateCompleted
- ... some test values on which I perform some calculation
Structure
Machine - Sample - Experiment - Completed - ...
m1 - s1 - e1 - <date> - ...
m1 - s1 - e2 - <date> - ...
m1 - s2 - e1 - <date> - ...
....
m2 - s3 - e1 - <date> - ...
....
On each machine, multiple experiments can be performed on a single sample.
My goal is to identify 5 latest -distinct- samples of each machine, and get all associated entries (entire rows, including all experiments per this sample).
I can't seem to find the next step once I group by Machine and order by DateCompleted descending.
I guess some sort of "DistinctBy (x => x.Sample)" is needed, but didn't manage to work it out.
Example: (say ordered by date descending already)
Machine - Sample - Experiment
m1 - s1 - e1 *
m1 - s1 - e2 *
m1 - s2 - e1 *
m1 - s2 - e2 *
m1 - s3 - e1 *
m1 - s4 - e1 *
m1 - s4 - e2 *
m1 - s5 - e1 *
m1 - s6 - e1
m1 - s6 - e2
...
I'd need all the lines marked "*" as output of my query - for each machine so.
I am struggling with writing even the SQL statement for this. If you know how would you write this in SQL, post it, I might get something out of it too.
EDIT:
Ok I tried going once again from bottom-up, and my first attempt was to identify the latest 5 samples.
The following query, with fixed value, works
var samples = (from c in db.Experiments
where c.Machine == "m1"
orderby c.Completed descending
select c.Sample).ToList().Distinct().Take(5)
I needed to add the "ToList()" because Distinct() messes it up otherwise.
Now, when I include this into another query, where I want the result per each machine - it does not work - it won't order it by descending Completed dates, but keeps the "random" order.
Why is that so?
var last5samples = (from t in db.Experiments
group t by new { t.Machine } into g
select new
{
Machine = g.Key.Machine,
Samples = (from c in db.Experiments
where c.Machine == g.Key.Machine
orderby c.Completed descending
select c.Sample).ToList().Distinct().Take(5)
});
EDIT 2:
Tried yet another approach, to enlist indeed what I need - all rows containing last 5 samples. This is quite slow, but "works", sort of, except for orderby descending not working.
I went with the "IN" approach first, but then saw that with LINQ I need to inverse the logic, and this is what I came up with:
var last5samples = from t in db.Experiments
where (from c in db.Experiments
where c.Machine == t.Machine
orderby c.Completed descending
select c.Sample).ToList().Distinct().Take(5)
.Contains(t.Sample)
select t;
My main issue now is how to make orderby descending work as expected.
I don't see why it works when it is a solo query, and when a subquery, it doesn't.