NHibernate可以使用的只读集合属性

时间:2010-07-28 12:32:39

标签: nhibernate collections fluent-nhibernate readonly-collection

我的域类包含如下所示的集合:

private List<Foo> _foos = new List<Foo>();
public virtual ReadOnlyCollection<Foo> Foos { get { return _foos.AsReadOnly(); } }

这为我提供了可以从类中修改的只读集合(即使用字段_foos)。

此集合映射如下(Fluent NHibernate):

HasMany(x => x.Foos).KeyColumn("ParentClassId").Cascade.All().Inverse().Access.CamelCaseField(Prefix.Underscore);

现在当我尝试使用这个系列时,我得到了:

无法转换'NHibernate.Collection.Generic.PersistentGenericBag 1[Foo]' to type 'System.Collections.Generic.List 1 [Foo]'类型的对象。

根据Unable to cast object of type NHibernate.Collection.Generic.PersistentGenericBag to List,这是因为集合需要作为接口暴露给NHibernate,以便NHibernate可以注入一个自己的集合类。

本文建议使用IList,但遗憾的是这个界面不包含AsReadOnly()方法,搞砸我的计划只向外界公开一个只读集合。

任何人都可以建议我可以使用哪种界面,一种满足相同要求的不同方法,或另一种不涉及这种挫折的职业?

由于

大卫

4 个答案:

答案 0 :(得分:7)

AsReadOnly()方法不是获取ReadOnlyCollection的唯一方法。

private IList<Foo> _foos = new List<Foo>();
public virtual ReadOnlyCollection<Foo> Foos { get { return new ReadOnlyCollection<Foo>(_foos); } }

另一个篮筐跳了起来。

答案 1 :(得分:5)

您的答案是一个很好的解决方案,但我只是将集合公开为IEnumerable<T>。这种方法存在一个小风险,因为这些可以转回IList。这是否是可接受的风险取决于申请。

答案 2 :(得分:3)

由于IList无法满足您的需求以及您(不幸)使用自动映射的方式,我会将Foos设置为受保护/私有IList'NHibernate友好'集合,然后创建公共阅读Foos的ReadOnlyCollection。

类似的东西:

    protected IList<Foo> MappableFoos { get; set; }
    public ReadOnlyCollection<Foo> ReadOnlyFoos { get { return new ReadOnlyCollection<Foo>(MappableFoos) } }

    // Mapping file
    HasMany(x => x.MappableFoos ).KeyColumn("ParentClassId").Cascade.All().Inverse().Access.CamelCaseField(Prefix.Underscore);

这样,唯一暴露的属性就是我可笑地称之为“ ReadOnlyFoos ”的属性。

答案 3 :(得分:1)

考虑将集合公开为IEnumerable而不是ReadOnlyCollection;它本质上为您提供相同级别的保护,而无需将您的模型绑定到特定的集合实现。有关进一步的讨论,请参阅this article