C# 处理类和NHibernate实体中的集合属性

C# 处理类和NHibernate实体中的集合属性,c#,nhibernate,oop,collections,C#,Nhibernate,Oop,Collections,我想知道在类中公开集合的推荐方法是什么,以及它与使用NHibernate实体时执行相同操作的方法是否有任何不同 让我解释一下。。。我的类公开集合属性时从未遇到过特定问题,例如: IList<SomeObjType> MyProperty { get; set; } IList MyProperty{get;set;} 将setter设置为protected或private有时可以让我更好地控制如何处理集合。 我最近看到了Davy Brion的这篇文章: Davy明确建议将集合作

我想知道在类中公开集合的推荐方法是什么,以及它与使用NHibernate实体时执行相同操作的方法是否有任何不同

让我解释一下。。。我的类公开集合属性时从未遇到过特定问题,例如:

IList<SomeObjType> MyProperty { get; set; }
IList MyProperty{get;set;}
将setter设置为protected或private有时可以让我更好地控制如何处理集合。 我最近看到了Davy Brion的这篇文章:

Davy明确建议将集合作为IEnumerables而不是let say列表,以禁止用户选择直接操作这些集合的内容。我能理解他的观点,但我并不完全相信,通过阅读他帖子上的评论,我不是唯一一个

然而,当涉及到NHibernate实体时,以他建议的方式隐藏集合是非常有意义的,尤其是当级联已经就位时。我想完全控制会话中的实体及其集合,而为集合属性公开AddXxx和RemoveXxx对我来说更有意义

问题是怎么做

如果我将实体的集合作为IEnumerables,我无法添加/删除元素,除非通过执行ToList()将它们转换为列表,这会生成一个新的列表,因此无法持久化任何内容,或者将它们强制转换为列表,这是一种痛苦,因为代理和延迟加载

总体思路是不允许检索实体并直接操纵其集合(add.remove元素),而只能通过我公开的方法,同时尊重集合持久性的级联


您的建议和想法将不胜感激。

将其公开为只读集合如何

IList<SomeObjType> _mappedProperty;

return new ReadOnlyCollection<SomeObjType> ExposedProperty
{
  get
  {
    return new ReadOnlyCollection(_mappedProperty);
  }
}
IList\u mappedProperty;
返回新的ReadOnlyCollection ExposedProperty
{
得到
{
返回新的ReadOnlyCollection(_mappedProperty);
}
}

我正在使用NHibernate,我通常将集合作为ISet保存,并使setter受到保护

ISet<SomeObjType> MyProperty { get; protected set; }
ISet MyProperty{get;protected set;}
我还为需要的集合属性提供AddXxx和RemoveXxx。这在大多数情况下对我来说都相当令人满意。但我要说的是,在某些情况下,允许客户机代码直接向集合中添加项是有意义的

基本上,我所看到的是,如果我在我的客户机代码中遵循的原则,而不太担心在我的域对象属性上强制执行严格的访问约束,那么我总会得到一个好的设计

那么

private IList<string> _mappedProperty;

public IEnumerable<string> ExposedProperty
{
    get { return _mappedProperty.AsEnumerable<string>(); }
}

public void Add(string value)
{
    // Apply business rules, raise events, queue message, etc.
    _mappedProperty.Add(value);
}
私有IList\u mappedProperty;
公共IEnumerable ExposedProperty
{
获取{return}mappedProperty.AsEnumerable();}
}
公共空添加(字符串值)
{
//应用业务规则、引发事件、队列消息等。
_mappedProperty.Add(值);
}
如果使用NHibernate映射到私有字段,即.\u mappedProperty,则此解决方案是可能的。您可以在访问和命名策略文档中阅读有关如何执行此操作的更多信息


事实上,我更喜欢这样映射我的所有类。最好由开发人员决定如何定义类的公共接口,而不是ORM。

ReadOnlyCollection是我想到的一个选项,它可以在非NHibernate上下文中很好地工作。当与NHibernate一起使用它时,我遇到了映射问题,因为它需要映射到一个单独的私有字段,在构造ReadOnlyCollection属性时必须初始化该字段,我正在寻找一种模式实践形式的替代方法。谢谢你的回答!谢谢你的回答。正如我在问题中提到的,我也在大多数情况下保护setter,但这并不禁止客户端代码使用集合直接添加/删除元素,绕过AddXxx/RemoveXxx方法中的逻辑。受保护仅防止客户端代码使用新的集合完全覆盖整个集合。您不需要可计算的,IList已经实现了IEnumerablet,这很有意义。我知道并建议其他人将私有财产映射到NHinernate,但从未设法与此案例建立联系。谢谢