将动态组件映射到不友好的数据表结构
本文关键字:数据表 结构 不友好 动态 组件 映射 | 更新日期: 2023-09-27 18:30:56
我有一个具有以下结构的数据表:
MyTable
-------------------------------------
rule_name char(20) PK
value_type char(20) PK
value varchar(50) not null
dt_last_update datetime not null
在此表中表示的数据中,我有一个感兴趣的rule_name
:
MailboxSC
我有两个不同的属性或称之为value_type
:
numberOfEmails
dateTimeReceived
我无法控制,也没有任何权力。
使用DynamicObject,我遵循了Ayende Rahien所能做到的:
使用 NHibernate 和 .NET 4.0 支持动态字段
所以现在,我的模型。
电子邮件指示器
public class EmailIndicator {
public EmailIndicator(HashtableDynamicObject hastableDynamicObject) {
this.hashtableDynamicObject = hashtableDynamicObject;
}
public virtual dynamic Attributes { get { return hashtableDynamicObject; } }
private readonly HashtableDynamicObject hashtableDynamicObject;
}
HashtableDynamicObject
public class HashtableDynamicObject : DynamicObject {
public HashtableDynamicObject(IDictionary dictionary) {
this.dictionary = dictionary;
}
public override bool TryGetMember(GetMemberBinder binder
, object[] indexes
, out object result) {
result = dictionary[binder.Name];
return dictionary.Contains(binder.Name);
}
public override bool TrySetMember(SetMemberBinder binder
, object[] indexes
, object value) {
dictionary[binder.Name] = value;
return dictionary.Contains(binder.Name);
}
public override bool TryGetIndex(GetIndexBinder binder
, object[] indexes
, out object result) {
result = dictionary[indexes[0]];
return dictionary.Contains(indexes[0]);
}
public override bool TrySetIndex(SetIndexBinder binder
, object[] indexes
, object value) {
dictionary[indexes[0]] = value;
return dictionary.Contains(indexes[0]);
}
private readonly IDictionary dictionary;
}
现在,我想将动态属性映射到rule_name
MailboxSC
的每一行,以便:
declare @emailCount int
declare @oldestDateTimeReceived datetime
select (
select valeur
from bqt001_pilotage_indicateurs
where nom_regle like 'boiteCourrielSC'
and type_valeur like 'nombreCourriels'
) as emailCount
, (
select valeur as olsdestDateTimeReceived
from bqt001_pilotage_indicateurs
where nom_regle like 'boiteCourrielSC'
and type_valeur like 'dateHeurePlusVieux'
) as oldestDateTimeReceived
into @emailCount
, @oldestDateTimeReceived
因此,我得到了所需的值,电子邮件数量和收到的最早日期/时间。
如何使用经典的NHibernateXML映射或Fluent NHibernate映射它?
链接的Ayende Rahien的文章提供了第一种方法:
<class name="Customer"
table="Customers">
<id name="Id">
<generator class="identity"/>
</id>
<property name="Name" />
<join table="Customers_Extensions" optional="false">
<key column="CustomerId"/>
<dynamic-component name="Attributes" access="field.lowercase">
<property name="EyeColor" type="System.String"/>
</dynamic-component>
</join>
</class>
所以我的猜测是:
<class name="EmailIndicatorModel">
<join table="MyTable" optional="false">
<dynamic-component name="Attributes" access="field.lowercase">
<property name="EmailCount" type="System.Int32" />
<property name="OldestDateTimeReceived" type="System.DateTime" />
<dynamic-component>
</join>
</class>
再说一次,这不允许我提及每个属性的鉴别器列rule_name
和value_type
。
我注定要使用旧式 ADO.NET 吗?
以下是一些关于我感兴趣的有趣的文章:
- 动态组件流畅自动映射
- 按代码映射 - 动态组件
- NHibernate将类属性映射到行而不是列(这篇文章把我引到了Ayende Rahien的文章)
我试图将我们使用NHibernate进行动态映射的可能性放在一起:
NHibernate动态映射
我个人确实使用并从<dynamic-component>
中获利很多,但正如上面的资源中所解释的,这需要不同的结构。
我。 IDictionary
因此,首先是客户非常普通/标准的表格:
// [Customer] table with key Customer_ID
Customer_ID, Name, Code,...
1, Abc, xxx,..
2, Def, yyy,..
键列Customer_ID
,以及描述客户的列。现在,如果我们想使用IDictionary
(或 C# 动态对象)和<dynamic-component>
来扩展客户,我们需要这样的表:
// [CustomerAttributes] - with a key referencing Customer table via Customer_ID
Customer_ID, Attribute1, Attribute2, Attribute3, ...
1, 123, 2014-01-01, FALSE, ...
2, 456, 2015-01-01, TRUE, ...
这是候选人
<join table="CustomerAttributes" optional="false">
<key column="Customer_ID"/>
<dynamic-component name="Attributes">
<property name="Prop1" column="Attribute1" type="int"/>
<property name="Prop2" column="Attribute2" type="DateTime"/>
<property name="Prop3" column="Attribute3" type="bool"/>
</dynamic-component>
</join>
优势?我们可以使用 ORDER BY。事实上,我们可以使用任何东西(选择 - 投影 - 请参阅此自定义ResultTransformer
与<dynamic-component>
一起使用,其中...
但是必须有标准表,其中属性(IDictionary
键)由列表示。
IDictionary<T,U>
在问题中提到的表格的情况下
MyTable
-------------------------------------
rule_name char(20) PK
value_type char(20) PK
value varchar(50) not null
dt_last_update datetime not null
我们需要IDictinary<T, U>
,并用<map>
映射:
<map name="Attributes" table="MyTable" >
<key column="rule_name"/>
<index-many-to-many column="value_type" class="ValueType"/>
<element column="value" type="string"/>
</map>
在本例中,我们映射的是ROWS
而不是列。这种方法不支持 ORDER BY,也不支持 SELECT(投影)...
摘要:表,其中 1) 在行中具有与我们的父表相关的值,2) 被某些列区分的表是<map>
候选