i currently have a linq to entities model set up as follows
each Sample has a collection Of Tests each Test has a collection of Results Each Result has Status property valuing whether it is Available or Completed
how would i write a linq query that would: get the samples that have available Results retaining only the tests that have available results and only the results in each test that are available
having trouble getting my head around this problem and help with getting this written would really help alot
Classes:
public class Sample
{
public Sample()
{
Tests = new List<Test>();
}
public int Id { get; set; }
public string IdText { get; set; }
public DateTime SampleDate { get; set; }
public DateTime LoginDate { get; set; }
public string Container { get; set; }
public string Product { get; set; }
public string Name { get; set; }
public string Status { get; set; }
public virtual SamplePoint SamplingPoint { get; set; }
public virtual SampleTemplate SampleTemplate { get; set; }
public virtual Customer ForCustomer { get; set; }
public virtual ICollection<Test> Tests { get; set; }
public class Test
{
public Test()
{
Results = new List<Result>();
}
public string Id { get; set; }
public string Status { get; set; }
public string Analysis { get; set; }
public string ComponentList { get; set; }
public virtual Instrument InstrumentUsed { get; set; }
public virtual ICollection<Result> Results { get; set; }
public virtual Sample ForSample { get; set; }
}
public class Result
{
public string Id { get; set; }
public string TestNumber { get; set; }
public string Status { get; set; }
public string Analysis { get; set; }
public string ComponentName { get; set; }
public string Text { get; set; }
public string Units { get; set; }
public double Value { get; set; }
public int OutOfRange { get; set; }
public DateTime SampledDate { get; set; }
public DateTime SampleLoginDate { get; set; }
public string SamplePoint { get; set; }
public virtual Sample ForSample { get; set; }
public virtual Test ForTest { get; set; }
}
If I understand your table structure then it's fairly easy to query down to get the results that you're interested in.
I put together a simple set of classes to test the results.
public static class db
{
public static List<Sample> Samples = new List<Sample>();
}
public class Sample
{
public string Name;
public List<Test> Tests = new List<Test>();
}
public class Test
{
public string Name;
public List<Result> Results = new List<Result>();
}
public class Result
{
public string Name;
public string Status;
}
And I created this set of test data:
From here it is easy to query the data down to just available results:
var query =
from s in db.Samples
from t in s.Tests
from r in t.Results
where r.Status == "Available"
select new { Sample = s.Name, Test = t.Name, Result = r };
Which gives me this data:
But that doesn't group the data by Sample and Test properly.
One way to do it properly is to create new Sample
& Test
objects that contain only the available results, like so:
var query =
from s in db.Samples
from rt in (
from t in s.Tests
from r in t.Results
where r.Status == "Available"
group r by t into rts
select new Test()
{
Name = rts.Key.Name,
Results = rts.ToList()
})
group rt by s into srts
select new Sample()
{
Name = srts.Key.Name,
Tests = srts.ToList()
};
This produces this result:
However, it might not be possible, or desirable, to create new instance of objects that look like actual entities but are not actually from the database. It might be possible to accidentally persist one of these objects back to the database and wipe out correct records!
So, an alternative, which I think is the best, is to create a nested structure that contains the unmodified database entities and includes the available tests in an extra properly all while keeping the nested structure!!
Here's how:
var query =
from s in db.Samples
from rt in
(from t in s.Tests
from r in t.Results
where r.Status == "Available"
group r by t into rts
select new
{
Test = rts.Key,
AvailableResults = rts.ToArray()
})
group rt by s into srts
select new
{
Sample = srts.Key,
AvailableTests = srts.ToArray()
};
And this produces:
With these results you still have access to the unchanged Sample
and Test
objects, but all filtered by the available results.
Let me know if this helps.
Without seeing your actual class structure, I'm hoping this can help in some way:
var testsWithAvailableResults = from test in dbContext.Tests
select new {
Results = (from result in test.Results where result.Status == "Available")
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.