Jas*_*lci 6 nhibernate fluent-nhibernate
我正在寻找一些方法来使用nhibernate在我的应用程序中动态映射数据库表类(或者如果其他一些ORM工作然后让我知道).我对nhibernate相当新,但我过去使用过实体框架.
我的大部分应用程序都将使用静态结构和流畅的nhibernate来映射它们.
但是,需要创建多个数据库表并将其映射到每个安装站点上的对象.这些都将作为基本结构(id,name等),但是根据它们捕获的数据类型,它们将具有其他字段.从一些阅读中我发现我可以使用xml中的"动态组件"映射来使用IDictionary Attributes属性添加字段.这是第一步,看起来相对简单.参考(http://ayende.com/blog/3942/nhibernate-mapping-dynamic-component)
第二步是我在努力的地方.我需要根据客户的需要定义表并映射它们.如上所述,每个表都有一组静态属性和一些动态属性.他们还需要引用静态"位置"类,如下所示
位置(STATIC)(id,coordinates)
----- DynamicTable1(DYNAMIC)(id,Name,location_id,DynamicAttribute1,DynamicAttribute2 ........)
----- DynamicTable2(DYNAMIC)(id,Name ,location_id,DynamicAttributeA,DynamicAttributeB ....)
我们需要能够像客户端需要一样创建/映射这些DynamicTables.对于大多数客户端站点,DynamicTable1,DynamicTable2等在某些方面很可能会有所不同.在nhibernate中有没有办法实现这一目标?数据库中表的创建/管理将在其他地方进行管理,我只需要一些方法将其映射到我的ORM中.
一点背景
这个应用程序将用于存储地质数据.由于地质数据因其位置而具有内在差异,地质学家正在使用不同的方法并寻找不同的元素(黄金,煤等),因此存储此信息的数据结构必须非常灵活.
看看NH 3.2 的新的按代码映射功能.它应该可以在运行时轻松创建新的表定义.与Fluent相比,您不需要编写映射类,只需在for循环中添加新类:
// 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));
});
}
Run Code Online (Sandbox Code Playgroud)
使用实体名称可以将实体存储到不同的表中并从中加载实体,即使它们被映射为同一个实体类.这就像Duck Typing With NHibernate..
相信我,这并不容易.如果您对每个NH专家都面临的重大挑战感兴趣,那就去吧.如果您只是想让它工作,您应该选择一种更经典的方式:创建一个静态数据库模型,它能够以通用方式存储动态数据(比如:名称值对).
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; }
}
Run Code Online (Sandbox Code Playgroud)
模板
<hibernate-mapping>
<class name="DynamicClass">
...
<dynamic-component name="DynamicData">
<!--placeholder -->
</dynamic-component>
</class>
</hibernate-mapping>
Run Code Online (Sandbox Code Playgroud)
替换<!--placeholder -->为生成的
<property
name="P1"
type="int" />
<property
name="P2"
type="string" />
Run Code Online (Sandbox Code Playgroud)
配置会话工厂
var sessionFactory = new NHibernate.Cfg.Configuration()
.AddXml(generatedXml)
... // DatabaseIntegration and other mappings
.BuildSessionFactory();
Run Code Online (Sandbox Code Playgroud)
询问
var query = session.CreateCriteria<DynamicClass>();
foreach (var restriction in restrictions)
{
query.Add(Restrictions.Eq(restriction.Name, restriction.Value))
}
var objects = query.List<DynamicClass>();
Run Code Online (Sandbox Code Playgroud)
编辑:ups我还没有意识到你每个客户需要多个桌子
选项1:
<class name="DynamicClass" table="tablenameplaceholder">每个动态类都有替换和不同的 Sessionfactory
选项2:
对动态类进行子类化并使用 TPS(每个子类表)映射
选项 3:仅使用 xml查看Stefans 的回答
<class name="DynamicTable1" class="DynamicClass" table="DynamicTable1">
| 归档时间: |
|
| 查看次数: |
8238 次 |
| 最近记录: |