4

我的域类具有如下所示的集合:

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.List1[Foo]”的对象。

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

文章建议改用 IList,但遗憾的是,这个接口不包含 AsReadOnly() 方法,打乱了我只向外界公开只读集合的​​计划。

谁能建议我可以使用什么界面,满足相同要求的不同方法,或者不涉及这么多挫折的替代职业?

谢谢

大卫

4

4 回答 4

7

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

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

又一个箍跳了起来。

于 2010-07-28T13:18:53.663 回答
5

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

于 2010-07-28T13:47:55.370 回答
3

由于 IList 不能满足您的需求以及您不(幸运地)使用 Automapping 的事实,我会将 Foos 设置为受保护/私有 IList 'NHibernate-friendly' 集合,然后创建一个公共 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 ”的属性。

于 2010-07-28T13:20:17.550 回答
1

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

于 2010-07-28T15:17:06.853 回答