如何映射通过只读属性访问的集合? [英] How do I map a collection accessed through a read only property?
问题描述
如何使用约定来映射零件集合?
public class Part
{
public virtual int Id {get;组; }
public virtual string Name {get;组; }
}
public class Car
{
private readonly List< Part> _parts = new List< Part>();
public virtual int Id {get;组; }
公共虚拟IList< Part>零件
{
得到{return _parts.AsReadOnly(); }
}
}
我已经尝试了这个约定,但总是期望没有下划线前缀的字段名称:
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ {
public void Apply(IOneToManyCollectionInstance实例)
{
instance.Access.ReadOnlyPropertyThroughCamelCaseField(CamelCasePrefix.Underscore);
$ / code $ / pre
我已经用1.2.0.694 2.0.0.698生成相同的结果:
$ b $ pre $ code>类'TestFluentNHibernate.Car'$中找不到字段' b $ b
首先,您的_parts成员无法阅读-只要。 NHibernate需要写访问权限来设置值/引用。要通过Parts属性返回一个真正的只读集合,你必须返回一个System.Collections.ObjectModel.ReadOnlyCollection。如果你只是返回f.ex,这也删除在读/写集合类型中找到的所有方法。 list.AsReadOnly()。以这种方式返回的只读列表仍然具有.Add()方法和其他编辑集合的方法,但是它们会导致运行时异常,因此返回ReadOnlyCollection开头是防止这种情况的一个很好的选择。
很多人似乎都喜欢返回一个IEnumerable,它也是只读的,但是它可以转换为一个List或者其他的读/写集合类型并且被改变。
您必须实现AddPart和RemovePart方法,以允许外部代码将项目添加到只读集合中。
您的约定看起来是正确的,我使用1.2.0.694完全相同的语法,我的约定:
instance.Key.Column(instance.EntityType.Name +Fk);
instance.Fetch.Subselect();
instance.Inverse();
instance.Cascade.All();
instance.Access.ReadOnlyPropertyThroughCamelCaseField(CamelCasePrefix.Underscore);
示例类:
public class Car
{
private List< Part> _部分;
$ b $ public Car()
{
//初始化成员集合_parts
_parts = new List< Part>();
}
public virtual int Id {get;组; }
//在此返回readonlycollection,ReadOnlyCollection实现
// IList< T> ;, ICollection< T>,IEnumerable< T> ;, IList,ICollection,IEnumerable,
//所以返回的列表可以是从这些基类继承的任何集合类型。
public ReadOnlyCollection< Part>零件
{
get {return new List< Part>(_ parts).AsReadOnly(); }}
$ b $ public AddPart(Part part)
{
//通常我不想重复
if(!_parts.Contains部分))
_parts.Add(part);
}
}
How do I map the collection of Parts using a convention?
public class Part
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class Car
{
private readonly List<Part> _parts = new List<Part>();
public virtual int Id { get; set; }
public virtual IList<Part> Parts
{
get { return _parts.AsReadOnly(); }
}
}
I have tried this convention but it always expects the field name without an underscore prefix:
public class HasManyConvention : IHasManyConvention
{
public void Apply(IOneToManyCollectionInstance instance)
{
instance.Access.ReadOnlyPropertyThroughCamelCaseField(CamelCasePrefix.Underscore);
}
}
I've tried it with the 1.2.0.694 and 2.0.0.698 builds with the same result:
"Could not find field 'parts' in class 'TestFluentNHibernate.Car'"
First of all, your _parts member can't be read-only. NHibernate needs write access to the member to set the value/reference. To return a truly read-only collection through the Parts property you have to return a System.Collections.ObjectModel.ReadOnlyCollection. This also "removes" all the methods found in the read/write collection types that are still there if you just return f.ex. list.AsReadOnly(). A read-only list returned in this way still have .Add() method and others to edit the collection, but they will cause a runtime exception so returning a ReadOnlyCollection to begin with is a great for preventing this possibility.
A lot of people seem to like returning an IEnumerable which is also read-only, but it can be cast to a List or other read/write collection type and changed that way.
You have to implement AddPart and RemovePart methods to allow external code to add and remove items to the read-only collection.
Your convention looks correct, I'm using the exact same syntax with 1.2.0.694 successfully, my convention:
instance.Key.Column(instance.EntityType.Name + "Fk");
instance.Fetch.Subselect();
instance.Inverse();
instance.Cascade.All();
instance.Access.ReadOnlyPropertyThroughCamelCaseField(CamelCasePrefix.Underscore);
Example class:
public class Car
{
private List<Part> _parts;
public Car()
{
// Initialize member collection _parts
_parts = new List<Part>();
}
public virtual int Id { get; set; }
// Return readonlycollection here, ReadOnlyCollection implements
// IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable,
// so the returned list can be any collection type inheriting from these base types.
public ReadOnlyCollection<Part> Parts
{
get { return new List<Part>(_parts).AsReadOnly(); } }
}
public AddPart(Part part)
{
// Usually I don't want duplicates
if (!_parts.Contains(part))
_parts.Add(part);
}
}
这篇关于如何映射通过只读属性访问的集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!