8

在我的應用程序中,我需要與多個數據庫交談。我在NHibernate中通過爲每個數據庫創建一個SessionFactory來處理它(我認爲這是正確的事情)。所以我有兩套模型(每個數據庫一套)和兩套Fluent NHibernate ClassMap<>映射。兩者都在同一個項目中(由命名空間分隔),我想保持這種方式。如何通過命名空間在流利NHibernate中添加映射

創建SessionFactory時出現問題。據我所看到的,功能NHibernate基本上已經添加映射兩種方法:

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserClassMap>()) 
    .Mappings(m => m.FluentMappings.Add<UserClassMap>() 

如果我使用的第一個重載,那麼我會得到廠家這兩個數據庫的所有映射。如果我使用第二個,我必須指定每個單獨的ClassMap。我想要像FluentMappings.AddFromNamespace()。有沒有辦法做到這一點?

回答

16

這是奇怪的是,FluentNHibernate支持這種類型的自動映射過濾的,而不是ClassMap秒。但是,通過擴展方法的魔力,自己添加此功能應該不會太困難。試試這個:

public static FluentMappingsContainer AddFromAssemblyOf<T>(
    this FluentMappingsContainer mappings, 
    Predicate<Type> where) 
{ 
    if (where == null) 
     return mappings.AddFromAssemblyOf<T>(); 

    var mappingClasses = typeof(T).Assembly.GetExportedTypes() 
     .Where(x => (typeof(IMappingProvider).IsAssignableFrom(x) 
       || typeof(IExternalComponentMappingProvider).IsAssignableFrom(x)) 
      && where(x)); 

    foreach (var type in mappingClasses) 
    { 
     mappings.Add(type); 
    } 

    return mappings; 
} 

...並使用它像這樣:

m.FluentMappings.AddFromAssemblyOf<UserClassMap>(t => t.Namespace.StartsWith("One.Of.The.Two.Namespaces")); 
+0

+1我發現了類似的東西,但這種方法更一般。 – 2011-06-01 20:20:38

+1

這並不映射SubClassMaps,因爲它們不能從IMappingProvider分配。 HTTP://計算器。com/a/6207141/206297具有應該檢查的MappingProviders的擴展列表。 – ngm 2015-06-15 14:39:12

0

沒有辦法做到這一點。我建議將名稱空間分隔成單獨的項目。切記:

當邏輯分隔有意義時,單獨命名空間,相同的項目。 當物理分離有意義時,單獨的名稱空間和單獨的項目。

在這種情況下,由於您無法通過nhibernate映射中的名稱空間進行分隔,所以物理分隔很有意義。但是,您可以通過使用.Where或ShouldMap配置的流暢自動映射解決此問題。查看流利的自動地圖,看看是否能讓你想要成爲你想要的地方。

0
... AutoMap.AssemblyOf<Person>().Where(x => x.Namespace.EndsWith("Domain")) ... 
+0

我沒有使用automappings,我使用ClassMap <>映射明確指定了我的映射。 – 2011-06-01 20:09:12

10

我結束了寫作,這是否對我的擴展方法。基本上它使用反射遍歷我感興趣的所有類型,並逐個添加它們。它基於AddFromAssemblyOf的實施。用法:

.Mappings(m => m.FluentMappings.AddFromNamespaceOf<UserClassMap>()) 

實現:

public static class FluentNHibernateExtensions 
{ 
    public static FluentMappingsContainer AddFromNamespaceOf<T>(
     this FluentMappingsContainer fmc) 
    { 
     string ns = typeof(T).Namespace; 
     IEnumerable<Type> types = typeof(T).Assembly.GetExportedTypes() 
      .Where(t => t.Namespace == ns) 
      .Where(x => IsMappingOf<IMappingProvider>(x) || 
         IsMappingOf<IIndeterminateSubclassMappingProvider>(x) || 
         IsMappingOf<IExternalComponentMappingProvider>(x) || 
         IsMappingOf<IFilterDefinition>(x)); 

     foreach(Type t in types) { 
      fmc.Add(t); 
     } 

     return fmc; 
    } 

    /// <summary> 
    /// Private helper method cribbed from FNH source (PersistenModel.cs:151) 
    /// </summary> 
    private static bool IsMappingOf<T>(Type type) 
    { 
     return !type.IsGenericType && typeof(T).IsAssignableFrom(type); 
    } 
} 

注意事項:

  • 名字是有點誤導,因爲它只是一個搜索裝配。它應該叫做AddFromAssemblyAndNamespaceOf,但這有點冗長。
  • 這不完全是面向未來的。如果未來版本的FNH添加或刪除了一些可映射的接口,它將不包含它們。

但它適用於我的目的。

+0

+1謝謝,非常有幫助! – 2011-09-28 05:22:14

+0

這正是我需要的 - 謝謝!這應該建立在FNH中。 – 2013-02-08 01:21:24