Reputation: 9
I have a classic graph of business objects connected like this one:
public enum TypeVoie
{
rue,
avenue,
route,
împasse
}
public class Ville
{
string nom;
public string Nom { get { return nom; } }
string codePostal;
bool capital;
public string id()
{
return nom + codePostal + capital.ToString();
}
}
/// <summary>
/// classe composé
/// </summary>
public class Adresse
{
int noRue;
string nomRue;
TypeVoie typeVoie;
public Ville ville { get; set; }
public Personne habitant { get; set; }
public Personne Habitant { get => habitant; set => habitant = value; }
public string id()
{
return noRue.ToString() + nomRue + typeVoie.ToString() + ville.id();
}
}
/// <summary>
/// classe de base composant
/// </summary>
public class Personne
{
/// <summary>
/// l'attribut ne marche pas
/// </summary>
public string nom { get; set; }
public string prenom { get; set; }
Dictionary<string, Adresse> adresses = new Dictionary<string, Adresse>();
public Dictionary<string, Adresse> Adresses { get => adresses; set => adresses = value; }
}
/// <summary>
/// classe composant
/// </summary>
public class Patient: Personne
{
private static int no = 0;
private string noSS;
public string IPP;
public string NoSS { get => noSS; set => noSS = value; }
public string LibelleIdentifiant { get; set; }
}
after that, i define a memory model of this object graph
/// <summary>
/// initialize a model
/// </summary>
public class InitModel1: InitModel
{
public Patient patient1;
public Patient patient2;
public Patient patient3;
public Patient patient4;
public List<Patient> patients = new List<Patient>();
public InitModel1()
{
Ville paris = new Ville("Paris", "78000", true);
Ville lyon = new Ville("Lyon", "69000", false);
Adresse adresse1 = new Adresse(10, "rue de la paix", TypeVoie.rue, paris);
Adresse adresse2 = new Adresse(69, "rue marietton", TypeVoie.rue, lyon);
Adresse adresse3 = new Adresse(35, "avenue de saxe", TypeVoie.avenue, lyon);
patient1 = new Patient("Berton", "isabelle", adresse1, "22372727320");
patient2 = new Patient("moussu", "marthe", null, null);
patient3 = new Patient("mornard", "xavier", adresse2, "66666242");
patient4 = new Patient("gallot", "frederic", adresse3, "45313248");
Adresse adresse4 = new Adresse(28, "impasse bellevue", TypeVoie.împasse, lyon);
patient4.Adresses.Add(adresse4.id(), adresse4);
patients.Add(patient1);
patients.Add(patient2);
patients.Add(patient3);
patients.Add(patient4);
}
}
I want to make a linq request to a graph of objects in memory, in order to make a partial copy of the model. So I wrote a linq request like this:
List<Patient> patientsCherches = patients;
var patientsTrouves = (from p in patientsCherches
where p.lstAddresses.FirstOrDefault(a => a.ville.Nom == "Lyon") != null
select p)
.ToList();
the request works and return only patient with good adress, but I have two problems with this request:
Upvotes: 0
Views: 223
Reputation: 39092
If the query was going to the database, this filtering could be done on the server side. In this case however the data is already in memory, so you will have to create a new instance if you don't want to lose data from the original instance.
You will create a new Patient
instance and set the list of addresses to a filtered result.
var patientsTrouves = (from p in patientsCherches
where p.lstAddresses.FirstOrDefault(a => a.ville.Nom == "Lyon") != null
select new Patient( /* initialize patient using "p" values */ ) { IPP = p.IPP, NoSS = p.NoSS,
lstAddresses = p.lstAddresses.Where( a => a.ville.Nom == "Lyon" ).ToList() } )
.ToList();
Here you can simply create a new patient instance without initializing the list of addresses.
var patientsTrouves = (from p in patientsCherches
where p.lstAddresses.FirstOrDefault(a => a.ville.Nom == "Lyon") != null
select new Patient( /* initialize patient using "p" variable */ ) )
.ToList();
I have a few additional suggestions for your code, just as potential improvements to get the readability better:
PascalCasingConvention
(each word has capital first letter), while private fields use camelCasingConvention
(each word has capital first letter except the first one)Id()
would be more readable as GetId()
lstAddresses
is not necessary, you can use just Addresses
instead, as it is clear there is more of them.IPP
. You can almost always use a public property instead. It is more future-proof.FirstOrDefault( condition ) != null
you can use Any( condition )
Upvotes: 2