我的实体框架POCO大多数(如果不是全部)具有虚拟功能。我需要这些函数是虚拟的,以便实体可以延迟加载。
如果我在构造函数中初始化Accommodations
,那么我将在构造函数中调用虚函数,这是不好的做法。
但是如果不在构造函数中,我如何初始化Accommodations
?
public class Venue
{
public Venue()
{
Accommodations = new HashSet<Accommodation>();
}
public virtual ICollection<Accommodation> Accommodations { get; set; }
}
答案 0 :(得分:15)
另一种选择是将setter标记为私有。这将消除在构造函数中调用虚拟成员的问题。
一旦这样做,您需要为呼叫者(EF除外)提供设置所需属性的方法。您可以使用重载的构造函数来传递一个包含列表,或者可选地封装您的集合(域驱动设计)并使用方法来添加/删除项目(注意,使用EF这会变成“hackish”,因为它缺乏对完全封装的支持集合,与NHibernate不同):
public class Venue
{
public Venue()
{
Accommodations = new HashSet<Accommodation>();
}
public Venue(ICollection<Accommodation> accommodations)
{
Accommodations = new List<Accommodation>(accommodations);
}
public virtual ICollection<Accommodation> Accommodations { get; private set; }
}
答案 1 :(得分:13)
public class Venue
{
private accommodations_ = new HashSet<Accommodation>();
public Venue() { }
public virtual ICollection<Accommodation> Accommodations
{
get { return accommodations_; }
set { accommodations_ = value; }
}
}
答案 2 :(得分:2)
使用延迟加载,您甚至不会初始化Accommodations
,直到它首次被访问,因此请保留null
。
您可以按如下方式进行换行,以使其自动初始化:
private ICollection<Accommodation> _accommodations;
public virtual ICollection<Accommodation> Accommodations {
get {
if (_accommodations == null)
{
// Initialize or load data here.
_accommodations = new HashSet<Accommodation>();
}
return _accomodations;
}
set {
_accommodations = value;
}
}
请务必阅读以下有关此解决方案的评论!
答案 3 :(得分:2)
使用C#6.0默认初始化,可以在不使用私有变量的情况下简化它:
public class Venue
{
public virtual ICollection<Accommodation> Accommodations {get; set; } = new HashSet<Accommodation>();
}