NHibernate dynamic mapping

家住魔仙堡 提交于 2019-12-03 14:51:25

Take a look at the new Mapping By Code functionality of NH 3.2. It should make it easy to create new table definitions at runtime. In contrast to Fluent, you don't need to write a mapping class, you just can add new classes in for loops:

// lookup all dynamic tables in the database using SQL or SMO or whatever
var dynamicTables = GetDynamicTables();

// map all dynamic tables
foreach(var table in dynamicTables)
{
  mapper.Class<MyGenericEntity>(ca =>
  {
      // use an entity name to distinguish the mappings.
      ca.EntityName(table.Name);
      ca.Id(x => x.Id, map =>
      {
          map.Column("Id");
          map.Generator(Generators.HighLow, gmap => gmap.Params(new { max_low = 100 }));
      });
      // map properties, using what ever is required: if's, for's ...
      ca.Property(x => x.Something, map => map.Length(150));
  });
}

Using the entity name you can store and load the entities to and from different tables, even if they are mapped as the same entity class. It is like Duck Typing With NHibernate..

Believe me, it won't be easy. If you are interested in a big challenge which impresses every NH expert, just go for it. If you just want to get it working you should choose a more classic way: create a static database model which is able to store dynamic data in a generic way (say: name value pairs).

Firo

see answer in Using nNHibernate with Emitted Code

class DynamicClass
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Location Location { get; set; }
    public virtual IDictionary DynamicData { get; set; }
}

Template

<hibernate-mapping>
  <class name="DynamicClass">
    ...
    <dynamic-component name="DynamicData">
      <!--placeholder -->
    </dynamic-component>
  </class>
</hibernate-mapping>

replace <!--placeholder --> with generated

<property
  name="P1"
  type="int" />
<property
  name="P2"
  type="string" />

configure Sessionfactory

var sessionFactory = new NHibernate.Cfg.Configuration()
    .AddXml(generatedXml)
    ...                      // DatabaseIntegration and other mappings
    .BuildSessionFactory();

Query

var query = session.CreateCriteria<DynamicClass>();

foreach (var restriction in restrictions)
{
    query.Add(Restrictions.Eq(restriction.Name, restriction.Value))
}

var objects = query.List<DynamicClass>();

Edit: ups i havent realised you need multiple tables per client

Option 1:

<class name="DynamicClass" table="tablenameplaceholder"> with replace and a different Sessionfactory for each dynamic class

Option 2:

Subclassing the dynamic class and use TPS (table per subclass) mappings

Option 3: see Stefans answer just with xml

<class name="DynamicTable1" class="DynamicClass" table="DynamicTable1">

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!