好的,伙计们,所以我不得不稍微延迟我承诺的回复,因为它无法正常工作。经过一整天的努力,现在我有一些有趣的事情要与您分享。
更准确地说,我的问题是:我有一个可以访问数据库的系统,而我希望在我的数据库中拥有:
- 静态表
- 动态表格。
为什么我想要动态表?我可以给你们举个例子:如果我想记录每个人在我的应用程序中所做的事情,并且我想以一种方式做到这一点,即使我的数据库中有很多日志,它也不会结束由于具有可扩展性(查询中有大量条件,一张表中要过滤大量数据),我必须每个用户日志有一个表。
静态表将是其他表,就像我在上面描述的类一样。
在 NHibernate 中没有一个简单的方法可以做到这一点。他们想将一个类和一个映射映射到一张表中,仅此而已。如果你想做其他事情,那么你必须愚弄图书馆。这就是我最终要做的事情:
在一个库项目中,我创建了一张这样的静态表:
public class GenericTableInfo
{
public virtual string name { get; set; }
public virtual int id { get; set; }
}
在同一个Library项目中,我的动态表的一个类(和xml,但我不会将xml添加到这个项目中),就像这样:
public class DynamicPeople
{
public virtual int id { get; set; }
public virtual string log { get; set; }
}
当我第一次生成要执行的查询时,使用我在上面描述的库的程序集,NHibernate 将创建静态表(具有 XML 和 Class 的表)并且不会创建与我的 DynamicPeople 课程。
在名为 AddTable() 的服务中,我必须执行以下操作:
- 1.在GenericTableInfo中添加表名(更准确地说是实体名);
- 获取包含在我的 GenericTableInfo 中的所有名称(因此,我在数据库中创建的所有动态表);
-
- 像这样创建一个会话:
public static ISession AddTable(string TableName, List TableNames, Databases db)
{
if ( !SessionFactories.ContainsKey( db ) )
{
SessionFactories.Add( db, null );
}
var _cfg = new Configuration();
_cfg.Configure( System.IO.Path.Combine( DatabaseConfigurationFiles[db] ) );
// Add table to the database
File.Move( @"C:\Generic.hbm.xml", @"C:\" + TableName + ".hbm.xml" );
string aux = File.ReadAllText(@"C:\" + TableName + ".hbm.xml");
aux = aux.Replace("generic", TableName);
File.WriteAllText( @"C:\" + TableName + ".hbm.xml", aux );
_cfg.AddFile(@"C:\" + TableName + ".hbm.xml");
var update = new SchemaUpdate( _cfg );
var sb = new StringBuilder();
TextWriter output = new StringWriter( sb );
update.Execute( true, true );
aux = aux.Replace( TableName, "generic" );
File.WriteAllText( @"C:\" + TableName + ".hbm.xml", aux );
File.Move( @"C:\" + TableName + ".hbm.xml", @"C:\Generic.hbm.xml" );
// Add dynamic tables to my mappings list.
if ( SessionFactories[ db ] == null )
{
var configuration = new Configuration();
configuration.Configure( DatabaseConfigurationFiles[ db ] );
configuration.AddAssembly( Assembly.GetExecutingAssembly() );
string filename = @"C:\Generic.hbm.xml";
string entityname = "generic";
string a = "";
for ( int i = 0 ; i < TableNames.Count() ; i++ )
{
File.Move( filename, @"C:\" + TableNames[ i ] + ".hbm.xml" );
filename = @"C:\" + TableNames[ i ] + ".hbm.xml";
a = File.ReadAllText( filename );
a = a.Replace( entityname, TableNames[ i ] );
entityname = TableNames[ i ];
File.WriteAllText( filename, a );
configuration.AddFile( filename );
configuration.ClassMappings.Last().EntityName = entityname;
configuration.ClassMappings.Last().Table.Name = entityname;
configuration.ClassMappings.Last().DiscriminatorValue = entityname;
}
File.Move( filename, @"C:\Generic.hbm.xml" );
filename = @"C:\Generic.hbm.xml";
a = File.ReadAllText( filename );
entityname = TableNames.Last();
a = a.Replace( entityname, "generic" );
File.WriteAllText( filename, a );
SessionFactories[ db ] = configuration.BuildSessionFactory();
}
else
{
DBStub.CloseSession( db );
return DBStub.OpenSession( db, TableNames );
}
return SessionFactories[ db ].OpenSession();
}
(对不起,第一行和最后一行没有被识别为代码,我是 StackOverflow 的菜鸟,它只是不想将这些行识别为代码。:()
修改我的配置通过更改我的 xml 实体名称和我的映射实体名称和表名称手动添加我的映射会欺骗库,因此它不知道它是相同的 xml,因此,不是相同的映射。
这样,您可以在使用 NHibernates 函数查询它们时找到您的表,使用它的实体名称作为键。然后,它们都可以映射到同一个类(在本例中,它们都将映射到 DynamicPeople)。
我没有看到其他人成功地尝试过这个,所以这是我今天给社区的 2 美分。如果有人有任何问题,请不要犹豫。 :)