NHibernate 3.2 Mapping by Code: Component Mapping

12 Oct 2011 by

Component mapping in NHibernate 3.2 Mapping by code provides a very flexible way. You can have multiples static method for returning Action<IComponentMapper<Address>> for the same component class. So that you can reuse it in different place with more customization.

In this example, we have Veteran class and Address class as a component.

 

Entity class files

Address.cs

  public class Address
  {
    public virtual string HouseNo { get; set; }
    public virtual string Street { get; set; }
    public virtual string Commune { get; set; }
    public virtual string District { get; set; }
    public virtual string Province { get; set; }
  }

Veteran.cs

  public class Veteran
  {
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Address Address { get; set; }
  }

Entity mapping class files

AddressMap.cs

  public class AddressMap
  {
    public static Action<IComponentMapper<Address>> Mapping()
    {
      return c =>
               {
                 c.Property(p => p.HouseNo);
                 c.Property(p => p.Street);
                 c.Property(p => p.Commune);
                 c.Property(p => p.District);
                 c.Property(p => p.Province);
               };
    }
  }

VeteranMap.cs

  public class VeteranMap : ClassMapping
  {
    public VeteranMap()
    {
      Id(p=>p.Id, map=>map.Generator(Generators.GuidComb));
      Property(p=>p.Name);
      Component(p=>p.Address, AddressMap.Mapping());
    }
  }

3 responses so far

NHibernate 3.2 Mapping by Code – Enforce Referential Integrity

28 Sep 2011 by

In the previous post, I show an example of a simple parent/child mapping by code in NHibernate 3.2. In this article, I will show how to enforce referential integrity in way the that deleting a parent record will yield to child record deletion as well.

The data model is exactly the same as previous post. The different is mapping technique.

ProvinceMap.cs

  public class ProvinceMap : ClassMapping
  {
    public ProvinceMap()
    {
      Id(p=>p.Id, map=>map.Generator(Generators.Assigned));
      Property(p => p.Code, map =>
                              {
                                map.Length(3);
                                map.NotNullable(true);
                              });
      Property(p=>p.Name);

      Bag(p => p.Districts, map =>
                              {
                                map.Key(k =>
                                          {
                                            k.Column("ProvinceId");
                                            k.OnDelete(OnDeleteAction.Cascade);
                                          });
                                map.Cascade(Cascade.All);
                                map.Inverse(true);
                              }, ce => ce.OneToMany());
    }
  }

DistrictMap.cs

  public class DistrictMap : ClassMapping
  {
    public DistrictMap()
    {
      Id(p=>p.Id, map=>map.Generator(Generators.Assigned));
      Property(p=>p.Name);
      ManyToOne(p=>p.Province, map=>map.Column("ProvinceId"));
    }
  }

NUnit Test

    [Test]
    public void Referential_integrity_should_work()
    {
      var province = new Province() {Id = 1, Code = "BMC", Name = "Banteay Meanchey"};
      var districtA = new District() {Id = 101, Name = "AA", Province = province};
      var districtB = new District() {Id = 102, Name = "BB", Province = province};

      province.Districts.Add(districtA);
      province.Districts.Add(districtB);

      using(var tx=NhSession.BeginTransaction())
      {
        NhSession.Save(province);
        tx.Commit();
      }

      var provinceBMC = NhSession.Get(province.Id);
      Assert.AreEqual("BMC", provinceBMC.Code);
      Assert.AreEqual(2, provinceBMC.Districts.Count);

      using(var tx = NhSession.BeginTransaction())
      {
        NhSession.Delete(provinceBMC);
        tx.Commit();
      }

      var queryDistrictA = NhSession.Get(districtA.Id);
      Assert.IsNull(queryDistrictA);
    }

 

5 responses so far

NHibernate 3.2 Mapping by Code – Basic Mapping

27 Sep 2011 by

NHibernate 3.2 is coming with default mapping interface that based on ConfORM interface NOT Fluent NHibernate interface. Since its released, there is little document on how to manage mapping by code with this new interface. So this post will contribute to the short.

I have a simple schema as follow:

I have these files to show you.

  1. App.Config, configuration file
  2. ApplicationContext.cs, manage NHibernate configuration and SessionFactory
  3. Province.cs, District.cs, a domain model as depicted in the figure above
  4. ProvinceMap.cs, DistrictMap.cs, a class-by-class mapping
  5. SchemaTest.cs, a drop and create schema for testing
  6. A full source code will be uploaded later while tutorial is completed
App.Config


  
    
  
  
    
  

ApplicaionContext.cs
  public class ApplicationContext
  {
    public static Configuration NHConfiguration { get; set; }
    public static ISessionFactory SessionFactory { get; set; }

    public static void AppConfigure()
    {
      #region NHibernate configuration

      NHConfiguration = ConfigureNHibernate();

      SessionFactory = NHConfiguration.BuildSessionFactory();

      #endregion
    }

    private static Configuration ConfigureNHibernate()
    {
      var configure = new Configuration();
      configure.SessionFactoryName("BuildIt");

      configure.DataBaseIntegration(db =>
      {
        db.Dialect();
        db.Driver();
        db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
        db.IsolationLevel = IsolationLevel.ReadCommitted;

        db.ConnectionStringName = "NH3";
        db.Timeout = 10;

        // enabled for testing
        db.LogFormattedSql = true;
        db.LogSqlInConsole = true;
        db.AutoCommentSql = true;
      });

      var mapping = GetMappings();
      configure.AddDeserializedMapping(mapping, "NHSchemaTest");
      SchemaMetadataUpdater.QuoteTableAndColumns(configure);

      return configure;
    }

    private static HbmMapping GetMappings()
    {
      var mapper = new ModelMapper();

      mapper.AddMappings(Assembly.GetAssembly(typeof(ProvinceMap)).GetExportedTypes());
      var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

      return mapping;
    }
  }
Province.cs
  public class Province
  {
    public Province()
    {
      Districts = new List();
    }

    public virtual long Id { get; set; }
    public virtual string Code { get; set; }
    public virtual string Name { get; set; }
    public virtual IList Districts { get; set; }
  }
District.cs
  public class District
  {
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Province Province { get; set; }
  }
ProvinceMap.cs
  public class ProvinceMap : ClassMapping
  {
    public ProvinceMap()
    {
      Id(p=>p.Id, map=>map.Generator(Generators.Assigned));
      Property(p => p.Code, map =>
                              {
                                map.Length(3);
                                map.NotNullable(true);
                              });
      Property(p=>p.Name);

      Bag(p => p.Districts, map => map.Key(k => k.Column("ProvinceId")), ce => ce.OneToMany());
    }
  }
DistrictMap.cs
  public class DistrictMap : ClassMapping
  {
    public DistrictMap()
    {
      Id(p=>p.Id, map=>map.Generator(Generators.Assigned));
      Property(p=>p.Name);
      ManyToOne(p=>p.Province, map=>map.Column("ProvinceId"));
    }
  }
SchemaTest.cs
  public class SchemaTest
  {
    [Test, Explicit]
    public void Create()
    {
      ApplicationContext.AppConfigure();
      new SchemaExport(ApplicationContext.NHConfiguration).Create(false, true);
    }

    [Test, Explicit]
    public void Drop()
    {
      ApplicationContext.AppConfigure();
      new SchemaExport(ApplicationContext.NHConfiguration).Drop(false, true);
    }
  }

5 responses so far