在NHibernate中使用IList,IEnumerable,ISet或ICollection有什么区别?

时间:2013-07-09 21:39:56

标签: nhibernate parent-child

对NHibernate实体类中的子对象集合使用IListIEnumerableISetICollection有什么区别?即:

public class Parent
{
    public virtual int IdParent { set; get; }

    public virtual IList<Child> Childs { set; get; }
    // Or
    public virtual ISet<Child> Childs { set; get; }
    // Or so on...
}

2 个答案:

答案 0 :(得分:11)

IList

  • 双向关系: NOT SUPPORTED 。 (因为引入了一个额外的索引列来维护子元素的顺序,这是子元素无法感知的)
  • 有序:是的
  • 类型:IList
  • 重复:允许
  • On添加元素:将加载整个集合以获取索引列值。如果儿童名单很大,请避免使用。

  • 双向关系:支持
  • 订购:否
  • 类型:IList
  • 重复:允许
  • 关于添加元素:只对数据库进行一次点击。没有性能问题。

的ISet

  • 双向关系:支持
  • 订购:否
  • 类型:ISet(直到NHibernate 3.0,它支持来自Iesi.Collections的接口)
  • 重复:不允许
  • 关于添加元素:将加载整个集合以检查重复项。如果儿童名单很大,请避免使用。

ICollection可以用作子集合的类型,可以通过三个NHibernate映射中的任何一个进行映射

Nhibernate Cookbook 3.0对使用每个系列有很好的解释,以防万一碰巧碰到它。

答案 1 :(得分:1)

任何IEnumerable都意味着延迟执行,因此当您的检索将要进一步处理下游(过滤是最明显的情况)时,您希望在查询中使用它。

如果不是这种情况,并且确实要确保不多次枚举该集合,则可以将其作为IList,ISet或ICollection使用。当你想确保集合可能有重复时,首选IList,而当你想确保集合没有欺骗时,首选ISet(设置行为在我的经验中更有用)。

IList和ISet 都是 ICollections,它暴露像Count这样的裸骨收集行为。在NHib上下文中,您可能会在使用Iesi集合而不是.net HashSet的实现中看到这一点,但这可能更多地与曾经没有.net HashSet的事实有关,然后NHib的能力存在滞后轻松使用它(但NHib 能够将ICollection映射到Iesi集)。

HTH