Search code examples
c#.netnhibernatenhibernate-mappingnhibernate-mapping-by-code

Mapping list of value objects in nhibernate


I have model House which has list of doors (door represents value object)

public class House : Entity<Guid>
{
   public int Id { get; set; }
   public List<Door> Doors { get; set; }
   ...
   public House(){
      Doors = new List<Door>();
   }
}

I'm using nhibernate mapping by code approach so I tried in mapping House

HouseMap.cs

public class HouseMap: ClassMapping<House>
{
   public HouseMap()
   {
      ...
      Component(c => c.Doors, DoorMap.Mapping());
   }
}

DoorMap.cs

public class DoorMap
{
    public static Action<IComponentMapper<Door>> Mapping()
    {
        return c =>
        {
            c.Property(p => p.Number);
            c.Property(p => p.Color);             
        };
    }
}

I'm getting error on HouseMap.cs

Component(c => c.Doors, DoorMap.Mapping());

CANNOT CONVERT LAMBDA EXPRESSION TO TYPE 'STRING' BEACUSE IT IS NOT A DELEGATE TYPE

What I'm doing wrong here? Other mapping of non list value objects are fine.


Solution

  • You should for sure use interface for your C# entity:

    public class House : Entity<Guid>
    {
        ...
        //public List<Door> Doors { get; set; }
        public virtual IList<Door> Doors { get; set; }
    

    And the mapping of the reference set is described here:

    Mapping-by-Code - Set and Bag by Adam Bar

    based on that, the Doors collection mapping should look like this (I prefer .Bag() with IList, rather than .Set() with a bit more specific ISet)

    Bag(x => x.Doors, c =>
    {
       ...
    

    and these are other available settings (extract from the link above):

    c.Fetch(CollectionFetchMode.Join); // or CollectionFetchMode.Select
                                       // , CollectionFetchMode.Subselect
    c.BatchSize(100);
    c.Lazy(CollectionLazy.Lazy); // or CollectionLazy.NoLazy, CollectionLazy.Extra
    
    c.Table("tableName");
    c.Schema("schemaName");
    c.Catalog("catalogName");
    
    c.Cascade(Cascade.All);
    c.Inverse(true);
    
    c.Where("SQL command");
    c.Filter("filterName", f => f.Condition("condition"));
    c.OrderBy(x => x.Name); // or SQL expression
    
    c.Access(Accessor.Field);
    c.Sort<CustomComparer>();
    c.Type<CustomType>();
    c.Persister<CustomPersister>();
    c.OptimisticLock(true);
    c.Mutable(true);
    ...