19

我的大多数(如果不是全部)实体框架 POCO 都具有虚拟功能。我需要这些函数是虚拟的,以便可以延迟加载实体。

如果我在构造函数中初始化Accommodations,那么我将在构造函数中调用虚函数,这是不好的做法。

Accommodations但是如果不在构造函数中,我该如何初始化?

public class Venue
{
    public Venue()
    {
        Accommodations = new HashSet<Accommodation>();
    }

    public virtual ICollection<Accommodation> Accommodations { get; set; }
}
4

4 回答 4

15

另一种选择是将设置器标记为私有。这将消除在构造函数中调用虚拟成员的问题。

完成此操作后,您需要为调用者(EF 除外)提供根据您的设计需要设置该属性的方法。您可以使用重载的构造函数来传递住宿列表,或者可以选择封装您的集合(域驱动设计)并使用方法来添加/删除项目(注意,使用 EF 这会变得“骇人听闻”,因为它缺乏对完全封装的支持集合,与 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; }
}
于 2014-05-28T16:20:06.277 回答
13
public class Venue
{
    private accommodations_ = new HashSet<Accommodation>();

    public Venue()  { }

    public virtual ICollection<Accommodation> Accommodations 
    {
        get { return accommodations_; }
        set { accommodations_ = value; }
    }
}
于 2013-04-17T08:49:22.867 回答
4

使用 C# 6.0 默认初始化,可以在不使用私有变量的情况下对其进行简化:

public class Venue
{
    public virtual ICollection<Accommodation> Accommodations {get; set; } = new HashSet<Accommodation>();
}
于 2017-11-07T10:12:44.097 回答
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;
    } 
}

请务必阅读以下有关此解决方案的评论!

于 2013-04-17T08:47:23.880 回答