Опрос детских коллекций на 2 уровня в LINQ - PullRequest
2 голосов
/ 27 октября 2011

У меня в настоящее время есть модель linq to entity, настроенная следующим образом

каждый образец имеет набор тестов, каждый тест имеет коллекцию результатов, каждый результат имеет свойство 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; }
}

Ответы [ 2 ]

7 голосов
/ 27 октября 2011

Если я понимаю структуру вашей таблицы, то довольно просто выполнить запрос вниз, чтобы получить результаты, которые вас интересуют.

Я собрал простой набор классов для проверки результатов.

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

И я создал этот набор тестовых данных:

Test Data

Отсюда легко запросить данные, чтобы получить только доступные результаты:

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

Что дает мне эти данные:

Bad Data

Но это не группирует данные по образцам и тестам должным образом.

Один из способов сделать это правильно - создать новые 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()
    };

Это дает такой результат:

New Data

Тем не менее, может оказаться невозможным или нежелательным создание нового экземпляра объектов, которые выглядят как реальные объекты, но на самом деле не из базы данных. Может быть возможно случайно сохранить один из этих объектов обратно в базу данных и стереть правильные записи!

Итак, альтернатива, которая, на мой взгляд, является наилучшей, заключается в создании вложенной структуры, которая содержит неизмененные объекты базы данных и включает в себя все доступные тесты в должном порядке, сохраняя при этом вложенную структуру !!

Вот как:

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

И это дает:

Good Data

С этими результатами у вас все еще есть доступ к неизмененным объектам Sample и Test, но все они отфильтрованы по доступным результатам.

Дайте мне знать, если это поможет.

0 голосов
/ 27 октября 2011

Не видя вашей реальной структуры класса, я надеюсь, что это может помочь каким-то образом:

var testsWithAvailableResults = from test in dbContext.Tests
                                    select new {
                                        Results = (from result in test.Results where result.Status == "Available")
                                     };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...