NHibernate 映射与来自多个源的多个关系的一对多关系
背景
我一直在开发一种应该与遗留应用程序结合使用的工具,但我遇到了一个小障碍。我花了大约一天的时间寻找这方面的线索,但我没有运气。
我试图映射一个表和多个其他表之间的关系,如下所示:
父表代表一个“字典”。该字典是可在(可怕的)遗留应用程序中的临时记录查询中使用的所有数据库字段的列表。每条记录都包含可以在其中找到项目的表和列、唯一标识“友好”名称、用于全局值查找表的键、确定如何提取这些查找值的标志以及定义如果正确设置了标志值,则运行 SQL 来获取查找数据。表名称为 [dictionary](表结构见下文。)
该标志可以具有以下四个值之一:
- FREEFORM
- STANDARD
- SYSTEM
- DYNAMIC
如果该标志设置为 FREEFORM,则最终用户可以输入他们想要的任何值。如果它是任何其他值,则必须从列表中选择一个值,如下所示:
- STANDARD:旧应用程序从两个表的“union all”查询中提取所有值,这两个表的唯一区别是一个表是基于财政年度的,另一个是“全球”值表。这些表保存所有“STANDARD”标记的字典记录的所有查找值。这两个表分别称为 [fy_lookup_values] 和 [lookup_values](表结构见下文)
- SYSTEM:如果字典表中的友好名称是“state”,则会提取其中所有状态的列表[状态]表;如果是国家/地区,则对 [国家/地区] 表执行相同的操作(表结构见下文)
- 动态:根据上述字典表中的动态 SQL 字段的查询来填充查找值。这些查询不会为所选列添加别名,甚至不会使用与上面其他两种查找类型中的列名称相似的名称。我将提供下面这些查询中使用的众多表之一的示例。
表结构
Table [dictionary]
token int not null identity primary key
name varchar(10) not null
table_name varchar(50) not null
column_name varchar(30) not null
lookup_key varchar(10) not null
lookup_type varchar(8) not null
query_text text
Table [lookup_values]
lookup_key varchar(10) not null primary key
lookup_value varchar(20) not null primary key
lookup_description text not null
Table [fy_lookup_values]
lookup_key varchar(10) not null primary key
lookup_value varchar(20) not null primary key
lookup_description text not null
fy_year_token int not null
Table [state]
state_code varchar(4) not null primary key
state_name varchar(30) not null
Table [country]
country_code varchar(4) not null primary key
country_name varchar(50) not null
Table [banks]
bank_token int not null identity primary key
bank_name varchar(50) not null
应用程序中的所有查找值检索都会获取两列:代码和描述。遗留应用程序当前根据列位置而不是名称来处理所有传入数据。
我无法触及数据库结构(甚至添加存储过程),也无法改变查找的完成方式,因为这些都被一些遗留应用程序使用,任何更改都会使管理层非常不高兴......我希望我可以,因为这只是这个应用程序让我头发变白的众多因素之一。所以...
我想我的主要问题是是否可以使用 NHibernate 以这种方式映射这些,以便当我获取字典项时,它的查找值会为我填充?如果可以的话,如何实现?我知道如果所有查找都以相同的方式完成,我可以,但我什至不知道是否可以根据外部获得的查询进行映射。
我希望这是有道理的,因为我花了一段时间才理解它。
编辑 以下是我正在努力实现的目标的一些示例。
我们在 [dictionary] 表中有以下记录:
token, name , table_name, column_name, lookup_key, lookup_type, query_text
1 , gender , customer , gender , gender , STANDARD , NULL
2 , addr_st , customer , addr_st , state , SYSTEM , NULL
3 , acct_type, cust_accts, type_code , acct_type , DYNAMIC , select type_code, descr from acct_types where active = 1
因此,在遗留应用程序中,当提取它们时,这里是执行以提取查找值的 SQL。
性别:
select lookup_value,
lookup_description
from lookup_values
union all
select lookup_value,
lookup_description
from lookup_values
where fy_year_token = @P1
地址 州:
select state_code,
state_name
from state
账户类型:
select type_code,
descr
from acct_types
where active = 1
BACKGROUND
I have been working on a tool that is supposed to work in conjuction with a legacy application, and I have hit a small brick wall. I have spent the last day or so searching for clues for this, but I have had no luck.
I am trying to map a relationship between a table and multiple other tables as follows:
The parent table represents a "dictionary." This dictionary is a list of all the database fields that can be used in ad-hoc records queries in the (horrible) legacy application. Each record holds the table and column where an item can be found, unique identfying "friendly" name, a key for use in a global value lookup table, and a flag that determines how those lookup values are pulled, and a text column that defines SQL to run to obtain lookup data if the flag value is set appropriately. The table name is [dictionary] (see below for table structure.)
The flag can have one of four values:
- FREEFORM
- STANDARD
- SYSTEM
- DYNAMIC
If the flag is set to FREEFORM, than the end user can enter any value they want. If it is any other value, then a value must be picked from a list as follows:
- STANDARD: The legacy application pulls all values from a "union all" query of two tables whose only difference is that one table is fiscal-year based, and the other is a "global" value table. These tables hold ALL lookup values for all "STANDARD" flagged dictionary records. These two tables are called [fy_lookup_values] and [lookup_values] respectively (see below for table structure)
- SYSTEM: If the friendly name in the dictionary table is "state" it pulls a list of all the states in the [state] table; if country, it does the same for the [country] table (see below for table structure)
- DYNAMIC: The lookup values are populated based on the query from dynamic SQL field described above in the dictionary table. These queries do not alias the selected columns with names even similar to the column names from the other two lookup types above. I will provide an example of one of the many tables used in these queries below.
TABLE STRUCTURES
Table [dictionary]
token int not null identity primary key
name varchar(10) not null
table_name varchar(50) not null
column_name varchar(30) not null
lookup_key varchar(10) not null
lookup_type varchar(8) not null
query_text text
Table [lookup_values]
lookup_key varchar(10) not null primary key
lookup_value varchar(20) not null primary key
lookup_description text not null
Table [fy_lookup_values]
lookup_key varchar(10) not null primary key
lookup_value varchar(20) not null primary key
lookup_description text not null
fy_year_token int not null
Table [state]
state_code varchar(4) not null primary key
state_name varchar(30) not null
Table [country]
country_code varchar(4) not null primary key
country_name varchar(50) not null
Table [banks]
bank_token int not null identity primary key
bank_name varchar(50) not null
All of the lookup value retreivals in the application grab two columns, a code and a description. The legacy application currently massages all incoming data based on column position, not name.
I cannot touch the database structure (even to add a store procedure), nor can I alter the way lookups are done, as these are all used by a few legacy applications and any changes would make management very unhappy... I wish I could, as this is only one of many things that makes my hair gray when it comes to this application. So...
My main question, I guess, is if it is possible to map these in such a way with NHibernate so that when I grab a dictionary item, it's lookup values are filled in for me? If it is possible, how? I know that if all of the lookups were done in the same way, I could, but I don't even know if it is possible to map based on externally obtained queries.
I hope this makes sense, as it took me a while to wrap my brain around it.
EDIT
Here are some examples of what I am trying to accomplish.
We have the following records in the [dictionary] table:
token, name , table_name, column_name, lookup_key, lookup_type, query_text
1 , gender , customer , gender , gender , STANDARD , NULL
2 , addr_st , customer , addr_st , state , SYSTEM , NULL
3 , acct_type, cust_accts, type_code , acct_type , DYNAMIC , select type_code, descr from acct_types where active = 1
So, in the legacy application, when they get pulled up, here is the SQL that is executed to pull up the lookup values.
Gender:
select lookup_value,
lookup_description
from lookup_values
union all
select lookup_value,
lookup_description
from lookup_values
where fy_year_token = @P1
Address State:
select state_code,
state_name
from state
Account Type:
select type_code,
descr
from acct_types
where active = 1
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以通过使用子类策略来做到这一点。因此,您的查找可以从名为 Lookup 的抽象类继承,您可以使用 每个具体类策略表。然后,您的字典对象可以使用适当的键拥有查找集合。
由于您复杂的获取策略,您可能需要实现某种 自定义加载程序 对于您的每个查找。需要注意的是,该加载器仅用于加载获取。如果您想针对这些查找编写 HQL 或条件查询,它将违背表和映射。但是,希望您不需要这样做。
You may be able to do this by using a subclass strategy. So your lookups can inherit from an abstract class called Lookup, which you can map using a table per concrete class strategy. Your dictionary object can then have a collection of Lookups using the appropriate keys.
Due to your complex fetching strategy you will likely need to implement some kind of custom loader for each of your lookups. The caveat is that this loader is only used for Load fetching. If you want to write an HQL or criteria query against these lookups it will go against the table and the mapping. However, hopefully you don't need to do that.