问题
I am developing a software that will serve as back-end for a data-ware house, in which fact definitions will be read from an xml file and corresponding fact/dimension tables will be created on the fly.
I have managed to make it work i.e. the code creates tables, updates table structure if possible otherwise drop table and make an new one, it can insert data into tables and we can query data-ware house from our client application as well. So far so good.
Now I have two problems
1) Too many sql statements. The problem: it will be night mare to maintain
2) Too many sql statements. The problem: I have been asked to support multiple databases that implies more sql statments.
I have to admit that I have not worked much with either of (n)Hibernate or Reflection.Emit.
But I was wondering how hard it would be to generate classes for my tables using Reflection.Emit and then use ActiveRecord/nHibernate to access data? So that I don't have to do the dirty work of dealing with a database directly.
回答1:
class Fact
{
public virtual int Id { get; set; }
IDictionary Properties { get; set; }
}
Template
<hibernate-mapping>
<class name="Fact">
<dynamic-component name="Properties">
<!--placeholder -->
</dynamic-component>
</class>
</hibernate-mapping>
replace <!--placeholder -->
with generated
<property
name="P1"
type="int" />
<property
name="P2"
type="string" />
Build
var doc = new System.Xml.XmlDocument();
doc.LoadXml(generatedXml);
new NHibernate.Cfg.Configuration()
.AddDocument(doc)
...
.BuildSessionFactory();
Query
var query = session.CreateCriteria<Fact>();
foreach (var restriction in restrictions)
{
query.Add(Restrictions.Eq(restriction.Name, restriction.Value))
}
var facts = query.List<Fact>();
SendBack(facts);
creating/dropping the table
var dialect = Dialect.GetDialect(config.Properties);
var defaultCatalog = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultCatalog, config.Properties, null);
var defaultSchema = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultSchema, config.Properties, null);
var createTableSql = config.GetClassMapping(typeof(Fact)).Table.SqlCreateString(dialect, config.BuildMapping(), defaultCatalog, defaultSchema);
var dropTableSql = config.GetClassMapping(typeof(int)).Table.SqlDropString(dialect, defaultCatalog, defaultSchema);
来源:https://stackoverflow.com/questions/6849602/using-nnhibernate-with-emitted-code