2010-03-29 63 views
0

如果數據庫有許多用於審計和版本控制的重複列,那麼使用NHibernate對其進行建模的最佳方式是什麼,而不必重複每個列的域模型中的類?如何在NHibernate中映射重複列而不創建重複屬性

數據庫中的每個表都重複這9列,名稱和類型相同,我不想在域模型中複製它。

我已閱讀文檔,並且看到了關於繼承映射的部分,但我無法看到如何在此場景中使其工作。這似乎是一個常見的情況,因爲幾乎每個我工作的數據庫幾乎在每個表中都有四個常見的審計列(CreatedBy,CreateDate,UpdatedBy,UpdateDate)。這個數據庫沒有什麼不同,只是它引入了另外五列,這些列對每個表都是通用的。

回答

0

這可以通過使用映射文件中的組件元素來完成。

基本的想法是創建一個類來保存公共屬性並從模型中的每個實體引用它。

然後你的映射文件中的引用添加到該屬性是這樣的...

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

使用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

+0

好主意使用T4,但我仍然有相同的九種屬性添加到我所有的實體,這是我想避免。 – 2010-03-29 01:39:19

+0

我想我沒有看到這個問題,只要你只需要在一個地方編輯九個屬性即可。 – 2010-03-29 07:17:16

+0

我不擔心編輯映射文件,你建議T4我已經使用代碼片段,我的問題是... 鑑於一個數據庫有許多用於審計和版本控制的重複列,什麼是最好的方法使用NHibernate進行建模,而不必在域模型中的每個類中重複每個重複列? – 2010-03-29 09:36:34

0

相反的映射,使用ConfORM

在很多情況下,它會爲你做的工作全部工作。如果沒有,定義約定和覆蓋非常容易。

2

使用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 
}