我的域类包含如下所示的集合:
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()方法,搞砸我的计划只向外界公开一个只读集合。
任何人都可以建议我可以使用哪种界面,一种满足相同要求的不同方法,或另一种不涉及这种挫折的职业?
由于
大卫
答案 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。