Hai bisogno di aiuto per lo sviluppo dell'espressione LINQ Lambda per filtrare su un programma
Domanda
Non riesco a trovare l'espressione lambda da chiamare in un elenco per filtrare correttamente una struttura di oggetti. Speravo che qualcuno qui potesse dare una mano. Sto usando .NET 3.5 e LINQ e il dominio dell'oggetto è impostato da Linq a SQL DBML. In particolare desidero utilizzare espressioni lambda .
La struttura dell'oggetto è quella in cui le persone hanno le impostazioni e un'impostazione è un nome di pianificazione, che corrisponde a un'altra classe di pianificazione con una data di inizio e una data di fine.
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; }
}
Le pianificazioni hanno date di inizio e fine e lo stato di una persona può essere Attivo o Pianificato.
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);
Voglio filtrare l'elenco delle persone creando un'espressione lambda che restituirà le persone con Stato = " Attivo " OPPURE con un ScheduleName contenente una data corrente tra la data di inizio e di fine. In altre parole, Jill dovrebbe apparire nell'elenco filtrato poiché è pianificata e utilizza ScheduleB, mentre ScheduleB è per il 2009 e oggi è il 17/06/2009.
Sto iniziando con
List<MyPerson> filter = persons.Select ( // and this is where I get stuck.
Grazie in anticipo per qualsiasi aiuto.
Soluzione
Devi ripensare a come stai memorizzando le informazioni. Le raccolte .NET non sono tabelle SQL e non dovresti usarle in questo modo. Detto questo, ecco la domanda che volevi:
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;
})
)
Immagina di avere una struttura di dati come:
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
)
)
Altri suggerimenti
Un problema è che stai iniziando con un Select
. Questo è per la proiezione: stai solo cercando di filtrare, quindi hai solo bisogno di Where
.
Un altro problema è che il tuo tipo MyPerson
non include una proprietà ScheduleName
o State
. In realtà non è chiaro come sia tutto pensato per stare insieme. Se potessi correggere il tuo esempio, sono sicuro che possiamo trovare il filtro.