【问题标题】:How do I map repeating columns in NHibernate without creating duplicate properties如何在不创建重复属性的情况下映射 NHibernate 中的重复列
【发布时间】:2010-03-30 07:40:32
【问题描述】:

给定一个数据库,其中有许多用于审计和版本控制的重复列,使用 NHibernate 建模它的最佳方法是什么,而不必重复域模型中每个类中的每个列?

数据库中的每个表都重复这九列,名称和类型相同,我不想在域模型中复制它。

我已经阅读了文档,并且看到了关于继承映射的部分,但我不知道如何使它在这种情况下工作。这似乎是一个常见的场景,因为我所处理的几乎每个数据库在几乎每个表中都有四个常见的审计列(CreatedBy、CreateDate、UpdatedBy、UpdateDate)。这个数据库没有什么不同,只是它引入了另外五列,这些列对每个表都是通用的。

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    使用Fluent NHibernate 创建您的映射文件。这允许您对映射文件使用继承。例如:

    public class AuditableClassMap<T> : ClassMap<T> where T : IAuditable
    {
        public AuditableClassMap()
        {
            Map(x => x.CreatedBy);
            Map(x => x.CreatedDate, "CreatedDt");
            Map(x => x.RevisedBy);
            Map(x => x.RevisedDate, "RevisedDt");
        }
    }
    
    public class CompanyMap : AuditableClassMap<Company>
    {
        // mapping for Company
    }
    

    【讨论】:

      【解决方案2】:

      使用 t4 代码生成,您应该能够编写一个代码生成文件,该文件输出一个 .hbm.xml 文件,其中定义了所有类。我设想如下。首先,创建一个扩展名为.tt的文件,并输入以下代码:

      <#@ template language="C#v3.5" #>
      <#@ output extension="hbm.xml" #>
      <?xml version="1.0" encoding="utf-8" ?>
      <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MyNameSpace">
      <#
      System.Collections.Generic.Dictionary<string, string> classes = new System.Collections.Generic.Dictionary<string, string>();
      classes.add("RootNameSpace.SubNameSpace.MyClass1", "Table1");
      
      foreach(string className in classes.keys)
      {
      #>
        <class name="<#=className#>, AssemblyName" table="<#=classes[className]#>">
          <id name="ID" column="EntityID" type="Int32">
            <generator class="native" />
          </id>
          <property name="Property1" />
          <property name="Property2" />
        </class>
      <#
      }
      #>
      </hibernate-mapping>
      

      最后一步是将输出文件的构建操作设置为嵌入式资源,您应该一切顺利。

      您可以在此处阅读有关 t4 代码生成的更多信息: http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx

      【讨论】:

      • 使用 T4 的想法不错,但我仍然必须向所有实体添加相同的九个属性,这是我想要避免的。
      • 我想我看不到问题,只要您只需在一个地方编辑九个属性。
      • 我不担心编辑映射文件,你建议 T4 我使用了代码 sn-ps,我的问题是......给定一个数据库,其中有许多重复列用于审计和版本控制,使用 NHibernate 对其建模的最佳方法是什么,而不必重复域模型中每个类中的每个重复列?
      【解决方案3】:

      不要手动映射,而是使用ConfORM

      在许多情况下,它会为您完成所有的工作。如果没有,则很容易定义约定和覆盖。

      【讨论】:

        【解决方案4】:

        这可以通过使用映射文件中的组件元素来完成。

        基本思想是创建一个类来保存公共属性并从模型中的每个实体引用它。

        然后在您的映射文件中添加对该属性的引用,如下所示...

        <component name="RecordMetadata" class="RecordMetadata" insert="true" update="true">
            <property name="UpdatedBy" />
            <property name="UpdatedDate" />
            <property name="CreatedBy" />
            <property name="CreatedDate" />
        </component>
        

        【讨论】:

          猜你喜欢
          • 2015-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-07
          • 2018-05-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多