为什么保护一对多关系属性的集合

时间:2012-09-11 20:42:33

标签: c# nhibernate fluent-nhibernate nhibernate-mapping

我有客户和订单实体。在使用流畅的hibernate为客户定义类时,为什么我们需要为Orders list属性指定“protected set”。

public virtual IList<Order> Orders { get; protected set; }

1 个答案:

答案 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