How can I map this:
public class Customer
{
private IList<Order> _orders;
public IEnumerable<Order>
GetAllOrders()
{
return _orders;
}
}
On the project page are some samples but none is about this situation.
There is this sample:
// model
public class Account
{
private IList<Customer> customers = new List<Customer>();
public IList<Customer> Customers
{
get { return customers; }
}
}
// mapping
HasMany(x => x.Customers)
.Access.AsCamelCaseField();
But it assumes that Account has public field Customers and that scenario is different as mine. I tried some possible options but none works:
HasMany(x => Reveal.Propertie("_orders"))
Private fields works fine in simple property mapping but collection mapping
is quite different. Any idea? Thanks
The easiest solution is to expose your collection as a public property Orders instead of the GetAllOrders() method. Then your mapping is
HasMany(x => x.Orders)
.Access.AsCamelCaseField(Prefix.Underscore);
and your class is
public class Customer
{
private IList<Order> _orders = new List<Order>();
public IEnumerable<Order> Orders
{
get { return _orders; }
}
}
If that doesn't work for you, it is possible to map private properties using Fluent NHibernate's Reveal mapping.
Edited to add: Having just done this, the correct answer is:
HasMany<Order>(Reveal.Property<Customer>("_orders")) etc.
The collection must be exposed as a protected virtual property to allow proxying:
protected virtual IList<Order> _orders { get; set; }
This answer put me on the right track.
Thanks.
Your solution is fine. However, there could be situations(hypotetical) when you dont want to reveal your private collection. This mapping scenario is not explained in your linked post because there is difference between mapping simple propertie as descibed in that post and collection mapping. My attempt to use HasMany(x => Reveal.Propertie("_orders")) failed because of raised exception.
You can map a completely private collection using Reveal.Member()
, but it has a specific and non-obvious restriction: the Expression
that HasMany()
accepts has to return either IEnumerable<TReferenced>
or object
.
For your class:
public class Customer
{
private IList<Order> _orders;
public IEnumerable<Order> GetAllOrders()
{
return _orders;
}
}
the following line will populate the _orders
collection:
HasMany(Reveal.Member<Customer, IEnumerable<Order>>("_orders"));
//additional mapping behaviors
For completeness - the following line gives a compiler error:
HasMany(Reveal.Member<Customer, IList<Order>>("_orders"));