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

tol*_*sm7 4 c# oop collections nhibernate

我想知道在一个类中公开一个集合的推荐方法是什么,以及它与使用NHibernate实体时做同样事情的方式有什么不同.

让我解释一下......我的类暴露集合属性时从未遇到过特定的问题:

IList<SomeObjType> MyProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)

将setter设置为protected或private会让我有时更多地控制我想要处理集合的方式.我最近遇到了Davy Brion的这篇文章:

http://davybrion.com/blog/2009/10/stop-exposing-collections-already/

戴维,显然建议将集合作为IEnumerables而不是让我们说列表,以禁止用户选择直接操作这些集合的内容.我可以理解他的观点,但我并不完全相信,通过阅读他的帖子上的评论,我不是唯一的.

然而,当谈到NHibernate实体时,以他提出的方式隐藏集合是特别有意义的,特别是当级联到位时.我希望完全控制会话及其集合中的实体,并且为集合属性公开AddXxx和RemoveXxx对我来说更有意义.

问题是怎么做?

如果我将实体的集合作为IEnumerables我没有办法向它们添加/删除元素而不通过执行ToList()将它们转换为Lists,这会产生一个新的列表,因此没有任何东西可以持久存在,或者将它们转换为Lists,这很痛苦因为代理和延迟加载.

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

非常感谢您的建议和想法.

Jul*_*anM 8

怎么样...

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);
}
Run Code Online (Sandbox Code Playgroud)

如果您使用NHibernate映射到私有字段,即._mappedProperty.您可以在此处的访问和命名策略文档中阅读有关如何执行此操作的更多信息.

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

  • 您不需要AsEnumerable <string>,IList <string>已经实现了IEnumerable <string> (4认同)