【问题标题】:Mapping dynamic component against non-friendly datatable structure?将动态组件映射到非友好的数据表结构?
【发布时间】:2014-12-20 06:35:47
【问题描述】:

我有一个具有以下结构的数据表:

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 那里得到了我所能做的:

Support dynamic fields with NHibernate and .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

所以我得到了我需要的值、电子邮件数量和最早收到的日期/时间。

如何使用经典的 NHibernate XML 映射或 Fluent NHibernate 映射它?

Linked 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_namevalue_type

我是否注定要使用旧式 ADO.NET?

这里有一些关于我感兴趣的有趣文章:

【问题讨论】:

    标签: c# nhibernate dynamic fluent-nhibernate


    【解决方案1】:

    我尝试将我们在使用 NHibernate 进行动态映射的可能性放在一起:

    NHibernate Dynamic mapping

    我个人确实使用&lt;dynamic-component&gt; 并从中获利很多,但正如上面资源中所解释的,这需要不同的结构。

    我。 IDictionary

    首先为客户准备一张非常常用/标准的表格:

    // [Customer] table with key Customer_ID
    Customer_ID, Name, Code,...
              1,  Abc,  xxx,.. 
              2,  Def,  yyy,.. 
    

    键列Customer_ID,以及描述客户的列。现在,如果我们想使用IDictionary(或C#动态对象)&lt;dynamic-component&gt;来扩展客户,我们需要这样的表:

    // [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。事实上,我们可以使用任何东西(SELECT - Projections - see this custom ResultTransformer working with &lt;dynamic-component&gt;, WHERE...)

    但必须有标准表,其中属性IDictionary的键)由列表示。

    IDictionary&lt;T,U&gt;

    如果问题中有上述表格

    MyTable
    -------------------------------------
    rule_name      char(20)     PK
    value_type     char(20)     PK
    value          varchar(50)  not null
    dt_last_update datetime     not null
    

    我们需要IDictinary&lt;T, U&gt; 并用 &lt;map&gt; 映射:

    <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) 由某些列区分是 &lt;map&gt; 的候选者

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 2015-01-28
      相关资源
      最近更新 更多