NHibernate / Fluent NHibernate 动态列映射
我有一个表,它的一些列在编译时是未知的。此类列可以是整数值,也可以是某个枚举值。有一个表保存了此类动态列的所有名称,并且还保存了列的类型。此“元表”具有以下列:
- DynamicColumnId (Pk)
- 名称
- TypeId(整数/枚举,作为来自单独表的 Fk)
整数列具有此表中的名称,而枚举列是来自该表的 Fk 列具有该名称的表,并进行一些修改(例如“DynamicTable”前缀)。
对于这种情况,我能想到的唯一解决方案是使用 Reflection.Emit 动态创建实体类和相应的映射类。不可否认,我是 NHybernate / Fluent NHybernate 的新手,它似乎是表之间相对简单的层次结构,所以我想验证我的解决方案并不像最初看起来那么丑陋......
我也欢迎完全解决方案忽略我的表层次结构,以便有效地获得相同的结果(即,枚举动态表上的行,遍历所有列,了解它们是否是枚举,如果是,也了解它们的可能值)。
(编辑:有关问题域的附加信息) 我最初包含了最少的细节,以避免与太多信息相关的混乱。 这个描述要复杂得多,但它揭示了这个设计背后的动机。
所涉及的应用程序旨在自动进行日志/转储分析。分析场景经常由日志/转储专家提供,因此,为了简化需求=>实现=>验证周期的典型流程,此类分析场景由专家直接作为 Iron Python 代码片段实现,将一些特定于域的构造注入到片段的范围中。每个片段都有一个与其相关的“上下文”。 “上下文”的一个示例可以是“产品”、“版本”等...因此,代码片段本身仅在某些上下文中被调用 - 这有助于通过消除分支来简化 Python 代码(您可以将其视为面向方面的编程,在某种程度上)。非专家可以在为各种上下文选择值后,使用具有给定代码上下文数据库的应用程序来分析日志/转储。 当专家决定需要新的上下文来对某个代码片段进行编目时,他可以添加一个上下文,指示它可能具有的可能值。将新上下文添加到数据库后,运行分析的非专家将可以选择为新添加的上下文选择值。 “动态表”是将代码片段与发出代码片段时存在的各种上下文(列)的值以及当时不存在的列的默认值相关联的表。
I have a table that, some of its columns are unknown at compile time. Such columns could either be of an integer value, or some Enum value. There is a table that holds all the names of such dynamic columns and also holds the column's type. This "metatable" has the following columns:
- DynamicColumnId (Pk)
- Name
- TypeId (Integer / Enum, as Fk from a separate table)
Integer columns have the Name from this table, whereas Enum columns are Fk columns from a table that has that Name, with some modification (e.g. a "DynamicTable" prefix).
The only solution I could think of for this situation is using Reflection.Emit to dynamically create an Entity class and a corresponding Mapping class. Admittedly, I'm new to NHybernate / Fluent NHybernate and it seems like a relatively simple hierarchy between the tables, and so I wanted to verify my solution isn't as ugly as it initially appears...
I would also welcome solutions that completely disregard my table hierarchy, in order to effectively acheive the same results (that is, to enumerate the rows on the dynamic table, going over all the columns, with knowledge of whether they are Enums and, if they are, their possible values as well).
(Edit: Additional information re problem domain)
I initially included minimal details, as to avoid Too-Much-Info related confusion.
This description is much more complex, but it unravels the motives behind this design.
The application involved is designed to automate log/dump analysis. Analysis-scenarios are frequently provided by the log/dump experts and so, in order to streamline the typical process of requirements=>implementation=>verification cycle, such analysis-scenarios are implemented by the experts directly as an Iron Python code snippet, with some domain-specific constructs injected into the snippets' scope. Each snippet has a "context" for which it is relevant. An example of "context" could be "product," "version," etc... So, the snippet itself is only invoked in certain contexts - this helps simplifying the Python code by eliminating branching (you could view it as Aspect Oriented Programming, to some extent). A non-expert could use the application, with a given code-context database, to analyze a log/dump, after choosing values for the various contexts.
When an expert decides that a new context is required for cataloging a certain code snippet, he could add a context, indicating the possible values it could have. Once a new context is added to the database, a non-expert that runs an analysis will be given the option to choose a value for the newly-added context.
The "dynamic table" is the table that associates a code snippet with values of the various contexts (columns) that existed when the snippet was issued, plus default values for the columns that did not exist at that time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不会声称完全理解您的场景,但在我看来,您最好使用键值存储,例如 Redis 或无模式数据库,例如 CouchDB 而不是SQL。对于关系数据库来说这似乎不是问题,但如果您确实需要使用 RDBMS,我会将 NHibernate 尽可能接近地映射到真实模式(DynamicColumnId、Name、TypeId),然后构建您需要的任何数据结构最重要的是。
I won't claim to fully understand your scenario, but it seems to me that you'd be better off using a key-value store such as Redis or a schema-less database like CouchDB instead of SQL. This doesn't seem to be a problem for a relational database, but if you really need to use a RDBMS I'd map NHibernate as closely as possible to the real schema (DynamicColumnId, Name, TypeId) then build whatever data structure you need on top of that.