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

Chr*_*ath 2 .net c# linq linq-to-entities asp.net-mvc-3

我目前有一个linq to entities模型设置如下

每个样本都有一个测试集合,每个测试都有一个结果集合每个结果都有一个Status属性,用于评估它是可用还是已完成

我将如何编写一个linq查询:获取具有可用结果的样本结果仅保留具有可用结果的测试,并且仅保留每个测试中可用的结果

无法解决这个问题,并帮助获得这个写真的帮助很多

类别:

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; }
}
Run Code Online (Sandbox Code Playgroud)

Eni*_*ity 7

如果我理解你的表格结构,那么查询下来以获得你感兴趣的结果是相当容易的.

我整理了一组简单的类来测试结果.

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;   
}
Run Code Online (Sandbox Code Playgroud)

我创建了这组测试数据:

测试数据

从这里可以轻松查询数据到可用结果:

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 };
Run Code Online (Sandbox Code Playgroud)

这给了我这个数据:

不好的数据

但是,这并没有通过Sample和Test正确地对数据进行分组.

正确执行此操作的一种方法是创建仅包含可用结果的新Sample&Test对象,如下所示:

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()
    };
Run Code Online (Sandbox Code Playgroud)

这会产生以下结果:

新数据

但是,创建看起来像实际实体但实际上不是来自数据库的对象的新实例可能是不可能或不可取的.有可能意外地将其中一个对象保留回数据库并清除正确的记录!

因此,我认为最好的另一种方法是创建一个包含未修改数据库实体的嵌套结构,并在保持嵌套结构的同时包含可用的额外测试!

这是如何做:

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()
    };
Run Code Online (Sandbox Code Playgroud)

这会产生:

好数据

有了这些结果,您仍然可以访问不变SampleTest对象,但所有可用的结果进行过滤.

如果这有帮助,请告诉我.