views:

111

answers:

1

Hi, 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;}
+1  A: 

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
Well, that is what I want to avoid - overriding each entity.
mynkow
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
Well, another day without any luck. Hey Berryl, can you give me more hints about this?
mynkow
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
Unfortunately I still have troubles. My mapping still has <bag>. 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
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
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

related questions