2

I am trying to map my collections with FNHib automapping. The problems that I want to solve are:

1) I want all my collections in the project to be mapped via private field. How can I say that globally?

2) Is there any way to automap bidirectional relationship without explicitly overriding each of my entities.

class OrganizationEntity example:

private ISet<> _collectionWarehouse;
public virtual IEnumerable<WarehouseEntity> CollectionWarehouse
{

get{return _collectionWarehouse; }

set{_collectionWarehouse = new HashedSet<WarehouseEntity>((ICollection<WarehouseEntity>)value)}

}

Class WarehouseEntity example:

public virtual OrganizationEntity Organization{get;set;}
Daniel Schilling
  • 4,829
  • 28
  • 60
mynkow
  • 4,408
  • 4
  • 38
  • 65
  • James Gregory on March 12, 2010 Currently, you can't. The automapper is very opinionated and inflexible, and it expects collections to be exposed as IList or ISet. I said the same in your other question, but this is something I'm actively working on improving. It's not much consolidation now though, I realise. Again, your options are either to live with the compromise in your domain (expose IList), override every occurrence, or not use automapping for these classes. http://support.fluentnhibernate.org/discussions/help/37-automapper-doesnt-map-hasmany-collections-which-uses-a-backing-field – mynkow Jul 08 '10 at 16:46

1 Answers1

3

You can map your collections to a private field 'globally' with the following convention:

// assumes camel case underscore field (i.e., _mySet)
public class CollectionAccessConvention : ICollectionConvention
{
    public void Apply(ICollectionInstance instance) {
        instance.Access.CamelCaseField(CamelCasePrefix.Underscore);
    }
}

Whenever you want to set a 'global' automap preference in FNH, think conventions. The you use the IAutoOverride on a given class map if you need to.

As far has the set (a HashSet is usually what I really want also) part, the last time I had to do some mapping, I did need to do an override, like:

   public class ActivityBaseMap : IAutoMappingOverride<ActivityBase>
{
    public void Override(AutoMapping<ActivityBase> m)
    {
        ...
        m.HasMany(x => x.Allocations).AsSet().Inverse();

    }
}

I do agree that should translate into a convention though, and maybe you can do that these days. Please post if you figure it out.

HTH,
Berryl

CODE TO USE A HASHSET as an ICollection =================

public virtual ICollection<WarehouseEntity> Wharehouses
{
    get { return _warehouses ?? (_warehouses = new HashSet<WarehouseEntity>()); }
    set { _warehouses = value; }
}
private ICollection<WarehouseEntity> _warehouses;
Berryl
  • 12,471
  • 22
  • 98
  • 182
  • Well, that is what I want to avoid - overriding each entity. – mynkow Jul 12 '10 at 17:50
  • btw ICollectionConvention is not working even with IList or ISet. Is there any order in which I should configure my alternations, overrides and conventions? – mynkow Jul 13 '10 at 18:11
  • Well, another day without any luck. Hey Berryl, can you give me more hints about this? – mynkow Jul 16 '10 at 08:39
  • There are two tricks you need to know about. First, NHib, or the combination of NHib / FNH (I don't remember exactly why not) doesn't map ISet. The second trick is that HashSet implements ICollection which NHib maps perfectly. So code similar to what I added to my answer should do it for you. Let me know if not. Peace – Berryl Jul 16 '10 at 10:57
  • Unfortunately I still have troubles. My mapping still has . I think that fluent automap only recognize ISet and IList when they are public exposed via property. So I am not sure if it is possible to generate this mapping. – mynkow Jul 16 '10 at 13:49
  • mynkow - two things. Here is a link to the original [post by Ayende](http://ayende.com/Blog/archive/2009/04/23/nhibernate-tidbit-ndash-using-ltsetgt-without-referencing-iesi.collections.aspx) on using the .Net HashSet, which is where I got the idea to use ICollection. Secondly, now that .Net 4.0 supports ISet it should be possible to use an FNH ISetConvention, although I don't have time to play with it right now. In the meantime, post your latest code so we can figure it out why a set isn't being used for your mapping. A HashSet declared an an ICollection *will* generate a set. Don't give up! – Berryl Jul 16 '10 at 16:36
  • Hi Berryl. Actually the problem is in FNHib. FNHib recognizes only ISet exposed in the property. Everything else is considered to be a Bag. Just... There is no way currently to do this. James also said that :( Btw, ICollection will expose Add() method and this is what I want to hide after all. – mynkow Jul 16 '10 at 21:59