我有客户和订单实体。在使用流畅的hibernate为客户定义类时,为什么我们需要为Orders list属性指定“protected set”。
public virtual IList<Order> Orders { get; protected set; }
答案 0 :(得分:2)
您无需在setter上指定protected
。这样做只是一个很好的设计。
如果在setter上没有指定访问修饰符,它将隐式具有与属性本身相同的访问修饰符(在您的情况下为public
)。当setter是public时,您的类的任何使用者都可以修改Orders
属性并将其设置为另一个实例。
public class Customer
{
public virtual IList<Order> Orders { get; set; }
}
var customer = new Customer();
customer.Orders = new List<Order>();
在setter上定义protected
访问修饰符时,只有继承的类才能修改该属性。对于任何其他使用者,Orders
属性显示为只读。这实际上是encapsulation。
NHibernate默认使用延迟加载。这是一种技术,其中一些属性(通常是列表)不会立即加载,而是在第一次使用时。 NHibernate通过代理实现这一点。动态创建的代理类继承自Entity
类,并覆盖其所有属性。这就是你对所有班级成员virtual
的原因。
而且,为了达到目的,当您定义protected set
时,您允许NHibernate的动态代理修改您的Orders
属性。 Orders
可以初始化为一些空的代理集合,当有人试图读取它时,将触发数据库加载,Orders
属性将被替换为从数据库加载的Order实例列表。
public class Customer
{
public virtual IList<Order> Orders { get; protected set; }
}
var customer = new Customer();
//customer.Orders = new List<Order>(); // error: can't modify property
var orderCount = customer.Orders.Count; // this will trigger lazy-loading