如何使用约定映射零件集合?
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(); }
}
}
我已经尝试过这个约定,但它总是希望字段名称没有下划线前缀:
public class HasManyConvention : IHasManyConvention
{
public void Apply(IOneToManyCollectionInstance instance)
{
instance.Access.ReadOnlyPropertyThroughCamelCaseField(CamelCasePrefix.Underscore);
}
}
我已经尝试使用1.2.0.694和2.0.0.698版本,结果相同:
"Could not find field 'parts' in class 'TestFluentNHibernate.Car'"
答案 0 :(得分:0)
希望这会有所帮助。尝试...
public class Car
{
protected virtual List<Part> _parts { get;set; }
public Car()
{
// Initialize "Parts" to not be null
this.Parts = new List<Part>();
}
public void PopulateParts (int someID)
{
// Do a call out to one of your helpers to populate "Parts"
// so it can be used.
//this.Parts = SomeCall(someID);
}
public virtual int Id { get; set; }
public virtual IList<Part> Parts
{
get { return this._parts; } // No need for "ReadOnly" since "protected set" will prevent changes outside of this class.
protected set { this._parts = value; }
}
}
受保护的集合将使其成为Car类之外的只读元素。 由于我没有看到你将如何填充零件,我创建了一个名为“PopulateParts”的调用作为一个钩子,因此你可以填充List。
答案 1 :(得分:0)
首先,您的_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> _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);
}
}