通常我认为这段代码是一个很好的设计:
查看该集合的私人二传手。所以没有人可以从schoolclass对象之外分配一个新的集合。
public class Schoolclass
{
public Schoolclass()
{
Pupils = new List<Pupil>();
}
public int SchoolclassId { get; set; }
public string SchoolclassCode { get; set; }
public List<Pupil> Pupils { get; private set; }
}
关于这种风格,我的数据提取方法不再起作用了:
服务层执行对SQLite数据提供程序的调用:
BL:
public IEnumerable<Schoolclass> GetAdministrationData()
{
var schoolclasses = adminDataProvider.GetSchoolclassList();
foreach (Schoolclass s in schoolclasses)
{
var pupils = adminDataProvider.GetPupilsBySchoolclassId(s.SchoolclassId);
s.Pupils = pupils;
foreach (Pupil p in pupils)
{
var documents = adminDataProvider.GetDocumentsByPupilId(p.Id);
p.Documents = documents;
}
}
return schoolclasses;
}
如果我现在有一个私人的定位器,上面的聚合将不起作用。
我还有另一种选择吗?或者我应该坚持我的装载技术?
答案 0 :(得分:1)
是的,你有很多选择:
将学生添加到已创建的列表中。
var pupils = adminDataProvider.GetPupilsBySchoolclassId(s.SchoolclassId);
s.Pupils.AddRange(pupils);
foreach (Pupil p in pupils)
{
var documents = adminDataProvider.GetDocumentsByPupilId(p.Id);
p.Documents.AddRange(documents);
}
请注意,公开List<T>
是一种不好的形式 - 最好公开Collection<T>
,但是您必须逐个添加项目。
如果你写这样的人:
public class Schoolclass
{
public Schoolclass()
{
Pupils = new BindingList<Pupil>();
// binding list descends from Collection<T>
}
public int SchoolclassId { get; set; }
public string SchoolclassCode { get; set; }
public Collection<Pupil> Pupils { get; private set; }
}
当然,有1000,000种方式甚至更多来编写这个和装载机。我喜欢懒惰加载自己。然后,当你有人要求学生时,你只加载它们。
答案 1 :(得分:1)
这是immutability的问题。您的List<Pupil>
属性仍然是可变的,即使使用私有的setter也是如此。
我无法直接设置您的Pupils属性:
myclass.Pupils = new List<Pupil>();
...但我可以修改:
var myClass = new SchoolClass();
myClass.Pupils.Add(new Pupil());
这是一篇很好的文章,讨论C#中不同类型的不变性: