C# 将NHibernate与古代数据库结合使用;“动态”;桌子

C# 将NHibernate与古代数据库结合使用;“动态”;桌子,c#,sql-server,nhibernate,fluent-nhibernate,C#,Sql Server,Nhibernate,Fluent Nhibernate,我有一个设计非常糟糕的遗留数据库,我需要为它编写一些应用程序。我根本不允许触碰数据库设计,因为这是一个脆弱的旧系统,由唾沫和祈祷维系在一起。我当然非常清楚,数据库本来就不应该这样设计,但现实生活中有时会遇到阻碍 对于我的新应用程序,我正在使用NHibernate(使用Fluent进行映射,使用NHibernate LINQ进行查询),并尝试将事情做好。因此,IoC和存储库以及比我所能统计的更多的接口。然而,DB结构让我有些头疼 该系统非常关注客户的概念,每个客户都生活在一个活动中。这些活动是由一

我有一个设计非常糟糕的遗留数据库,我需要为它编写一些应用程序。我根本不允许触碰数据库设计,因为这是一个脆弱的旧系统,由唾沫和祈祷维系在一起。我当然非常清楚,数据库本来就不应该这样设计,但现实生活中有时会遇到阻碍

对于我的新应用程序,我正在使用NHibernate(使用Fluent进行映射,使用NHibernate LINQ进行查询),并尝试将事情做好。因此,IoC和存储库以及比我所能统计的更多的接口。然而,DB结构让我有些头疼

该系统非常关注客户的概念,每个客户都生活在一个活动中。这些活动是由一个旧应用程序创建的。系统中的每个活动都在名为“活动设置”的表中定义。此表的其中一列只是一个名为“table”的文本列,它指的是与活动设置中的活动条目同时创建的数据库表。此表的名称与活动的名称相关,活动的名称几乎可以是客户想要的任何内容(在SQLServer(2000或2005)给定的约束范围内)。顾客住在这些桌子上

这就是挑战#1-在运行时之前我不会知道表名。它会随着站点的变化而变化——我想没有静态映射

更糟糕的是,我们还有挑战2——这个活动表在结构上也是动态的,这意味着它总是有一定数量的列(客户id、姓名、电话号码、电子邮件地址和其他内务管理信息),然后还有另外两组列,根据客户的要求逐个添加

旧的应用程序使用SQL获取表中的列名,然后将不知道的列名作为“自定义字段”添加到应用程序中。我需要处理这件事

我知道我可能无法简单地通过使用映射魔法来处理这些挑战,并且我准备在我从NHibernate获得的ORM优点之外再做一些难看的SQL(这里有20个“静态”表,NHibernate可以很好地处理这些表)-但是怎么做呢

我将创建一个客户实体,我想我可以通过像直接SQL一样手动填充它

SELECT * FROM SomeCampaignTable WHERE id=<?>
然后再次执行一些手动操作来配置我的对象以处理自定义字段

我的问题很简单-我如何在NHibernate中做到这一点?这是一种简单的方法来运行我自己的SQL,然后遍历结果,还是有一种更优雅的方法来减轻痛苦

虽然我很欣赏这个数据库设计属于某个酷刑博物馆,但像“添加一些视图”或“更改数据库”这样的回答对我没有帮助——如果我提出这样的建议,我会被枪毙


谢谢你能帮我在这里保持理智

您可以使用本机SQL实体查询使用NHibernate。忘记Linq2NH吧——我不会推荐Linq2NH用于任何严肃的应用程序

查看此页。
13.1.2. 实体查询

你可以这样做: 基于“假”表映射实体,以使NHibernate在编译映射文档时感到高兴(我知道您说过您不能更改DB,但希望可以创建一个空表以使NH高兴)

然后按照上面的13.1.2运行如下查询:

sess.CreateSQLQuery("SELECT tempColumn1 as mappingFileColumn1, tempColumn2 as mappingFileColumn2, tempColumn3 as mappingFileColumn3 FROM tempTableName").AddEntity(typeof(Cat));

NHibernate应该将您返回的列与映射实体缝合在一起,并为您提供“Cat”类型的实体,其中填充了所有属性。不过我在这里猜测,我不确定这是否有效,这是我唯一能想到的使用NHibernate的方法,因为您在编译时不知道表/列。您绝对不能使用HQL、Criteria、Linq2NH,因为您在编译时不知道表和列,HQL等都会将映射转换为映射的列名以生成底层SQL。我认为本地SQL查询是唯一的方法

谢谢-这让我走上了正轨!使用CreateSQLQuery和.SetResultTransformer(Transformers.AliasToEntityMap)可以从表中获取所需的所有信息。它很脏,但能用!谢谢只是出于好奇-为什么Linq2NH不好有什么特别的原因吗(不是针对这个特定场景,只是一般情况)?Linq2NH仍然非常不成熟。它只支持基本查询,不支持缓存、即时加载。。。我在当前的应用程序中使用了6个月,后来因为懒得学习HQL/Criteria而放弃了它,然后花了一个星期的时间将其删除。Linq2NH易于学习,易于操作,但如果你花一点时间学习HQL/标准,你将拥有更多的能力和控制能力,你的应用程序也会更快。祝你好运听起来你手头有一个该死的项目!谢谢到目前为止,我也使用过Linq2NH,但我想我可以在没有那一周(或任何需要的时间)的情况下过日子,以后不再使用它。。感谢您的帮助、建议和祝愿,我将很幸运地从这个项目中脱身,头上留有头发。:)
sess.CreateSQLQuery("SELECT tempColumn1 as mappingFileColumn1, tempColumn2 as mappingFileColumn2, tempColumn3 as mappingFileColumn3 FROM tempTableName").AddEntity(typeof(Cat));