我有一个像这样连接的经典业务对象图:
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; }
}
之后,我定义了此对象图的内存模型
/// <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);
}
}
我想向内存中的对象图提出LINQ请求,以便制作模型的部分副本。所以我写了这样的linq请求:
List<Patient> patientsCherches = patients;
var patientsTrouves = (from p in patientsCherches
where p.lstAddresses.FirstOrDefault(a => a.ville.Nom == "Lyon") != null
select p)
.ToList();
请求有效,只返回具有良好地址的患者,但我在此请求中有两个问题:
- 请求返回detter4对象的两个地址,即使第二个地址不在里昂上:如何修改Where子句仅返回好地址?
- 我只想在不连接地址的情况下返回患者对象,我该怎么做?因为LINQ请求可以返回对象集合,但无需复制或修改它们,所以我不知道如何返回没有链接对象的对象的副本
如果查询要进入数据库,则可以在服务器端进行此过滤。在这种情况下,但是数据已经在内存中,因此,如果您不想丢失原始实例的数据,则必须创建一个新实例。
仅选择地址
您将创建一个新的Patient
实例,并将地址列表设置为过滤结果。
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();
只有没有地址的患者
在这里您可以简单地创建一个新的患者实例而不初始化地址列表。
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();
其他建议
我还有一些有关您的代码的建议,就像可以改善可读性的潜在改进:
:- 明确的命名惯例。通常,属性和方法使用
PascalCasingConvention
(每个单词都有首字母(,而私有字段使用camelCasingConvention
(每个单词都有首字母,除第一个字母外( - 理想情况下,方法名称应包括动词,以指示它们执行动作的事实,并且实际上是方法,而不是属性。例如,
Id()
更可读性为GetId()
- 该属性的名称应具有自描述性,并且如果不需要的话,则不必描述数据类型 - 不需要
lstAddresses
,您可以仅使用Addresses
,因为很明显,还有更多。 - 避免使用
IPP
之类的公共字段。您几乎可以始终使用公共财产。它是更适合未来的。 - 而不是
FirstOrDefault( condition ) != null
您可以使用Any( condition )