简体   繁体   English

在LINQ中查询子集合2个级别

[英]Querying Child Collections 2 levels deep in LINQ

i currently have a linq to entities model set up as follows 我目前有一个linq to实体模型,设置如下

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 每个样本均具有测试集合每个测试均具有结果集合每个结果具有Status属性,用于评估其是否可用或已完成

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 我将如何编写一个linq查询,该查询将:获得具有可用结果的样本仅保留具有可用结果的测试,并仅保留每个可用测试中的结果

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: 正确执行此操作的一种方法是创建仅包含可用结果的新SampleTest对象,如下所示:

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. 有了这些结果,您仍然可以访问未更改的SampleTest对象,但是所有对象均按可用结果过滤。

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")
                                     };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM