Нужна помощь в разработке лямбда-выражения LINQ для фильтрации по расписанию

StackOverflow https://stackoverflow.com/questions/1009203

  •  06-07-2019
  •  | 
  •  

Вопрос

Мне трудно найти лямбда-выражение для вызова списка, чтобы правильно отфильтровать структуру объекта. Я надеялся, что кто-то здесь сможет помочь. Я использую .NET 3.5, и LINQ и домен объекта настроен с Linq на SQL DBML. Я специально хочу использовать лямбда-выражения .

В объектной структуре есть настройки, в которых люди имеют настройки, а одна настройка - это имя расписания, которое соответствует другому классу расписания с начальной датой и датой окончания.

public class MyPerson
{
    public int ID { get; set; }
    public List<MySetting> Settings { get; set; }
}

public class MySetting
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

public class MySchedule
{
    public string ID { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

}

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

    List<MySchedule> schedules = new List<MySchedule>();
    MySchedule scheduleA = new MySchedule { ID = "ScheduleA", StartDate = Convert.ToDateTime("1/1/2008"), EndDate = Convert.ToDateTime("12/31/2008") };
    MySchedule scheduleB = new MySchedule { ID = "ScheduleB", StartDate = Convert.ToDateTime("1/1/2009"), EndDate = Convert.ToDateTime("12/31/2009") };
    schedules.Add(scheduleA);
    schedules.Add(scheduleB);

    List<MySetting> settingsJill = new List<MySetting>();
    MySetting settingFirstName = new MySetting { ID = 1, Name = "FirstName", Value = "Jill" };
    MySetting settingScheduleName = new MySetting { ID = 2, Name = "ScheduleName", Value = "ScheduleB" };
    MySetting settingState = new MySetting { ID = 3, Name = "State", Value = "Scheduled" };  // Jill uses ScheduleB
    settingsJill.Add(settingFirstName);
    settingsJill.Add(settingScheduleName);
    settingsJill.Add(settingState);

    List<MySetting> settingsBill = new List<MySetting>();
    settingFirstName = new MySetting { ID = 1, Name = "FirstName", Value = "Bill" };
    settingScheduleName = new MySetting { ID = 2, Name = "ScheduleName", Value = "ScheduleA" };
    settingState = new MySetting { ID = 3, Name = "State", Value = "Scheduled" };              // Bill is Scheduled last year
    settingsBill.Add(settingFirstName);
    settingsBill.Add(settingScheduleName);
    settingsBill.Add(settingState);

    List<MySetting> settingsJane = new List<MySetting>();
    settingFirstName = new MySetting { ID = 1, Name = "FirstName", Value = "Jane" };
    settingScheduleName = new MySetting { ID = 2, Name = "ScheduleName", Value = "ScheduleA" };
    settingState = new MySetting { ID = 3, Name = "State", Value = "Active" };              // Jane is Active
    settingsJane.Add(settingFirstName);
    settingsJane.Add(settingScheduleName);
    settingsJane.Add(settingState);

    List<MyPerson> persons = new List<MyPerson>();
    MyPerson Jane = new MyPerson { ID = 1, Settings = settingsJane };
    MyPerson Jill = new MyPerson { ID = 2, Settings = settingsJill };
    persons.Add(Jane);
    persons.Add(Jill);
    persons.Add(Bill);

Я хочу отфильтровать список лиц, создав лямбда-выражение, которое будет возвращать людей с State = " Active " ИЛИ с именем ScheduleName, содержащим текущую дату между начальной и конечной датой. Другими словами, Джилл должна появиться в отфильтрованном списке, поскольку у нее запланировано и она использует ScheduleB, а ScheduleB на 2009 год, а сегодня 17.06.2009.

Я начинаю с

List<MyPerson> filter = persons.Select (  // and this is where I get stuck.

Заранее спасибо за любую помощь.

Это было полезно?

Решение

Вам необходимо переосмыслить способ хранения информации. .NET Collectionns не являются таблицами SQL, и вы не должны использовать их так. При этом, вот запрос, который вы хотели:

Persons.Where(person => 
  person.Settings.Any(setting=>
      (setting.Name == "State" && setting.Value=="Active")) ||
  person.Settings
      .Where(setting=> setting.Name == "ScheduleName")
      .Any(setting => { var sch = schedules
           .First(schedule=>schedule.ID == setting.Value);
           return sch.StartDate < DateTime.Now && sch.EndDate > DateTime.Now; 
      })   
)

Представьте, что у вас есть такая структура данных:

class Person { 
    Dictionary<string, string> Settings;
    List<MySchedule> Schedules;
}

then your query would be

Persons.Where(person =>
   Person.Settings["State"] == "Active" ||
   Person.Schedules.Any(schedule => 
       Datetime.Now > schedule.StartTime &&
       DateTime.Now < schedule.EndTime
   )
)

Другие советы

Одна из проблем заключается в том, что вы начинаете с Select . Это для проекции - вы просто пытаетесь фильтровать, поэтому вам нужно только Где .

Другая проблема заключается в том, что ваш тип MyPerson не содержит свойство ScheduleName или State . Это действительно не ясно, как все это означает, чтобы держаться вместе. Если бы вы могли исправить свой пример, я уверен, что мы можем придумать фильтр.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top