2012-09-14 43 views
1

我一直在NHibernate> = 3.2中使用NHibernate映射的代碼功能,非常喜歡它。現在我想開始在一個現有項目中使用它,我們有大約80個*.hbm.xml文件。一次性更改所有*.hbm.xml文件是不可行的,因此我希望使用代碼映射來創建新的映射,並逐步轉換現有的XML文件。有沒有一種方法來結合XML文件和NHibernate中的代碼映射

我試着將一個XML文件轉換爲代碼映射,並修改了我的配置構建代碼以引入代碼映射。下面是該代碼的摘錄:

private void AddMappings(Configuration configuration, Assembly assembly) 
{ 
    // add mappings from embedded *.hbm.xml files 
    configuration.AddAssembly(assembly); 

    // add mappings from map by code 
    var modelMapper = new ModelMapper(); 
    modelMapper.AddMappings(assembly.GetExportedTypes()); 
    var mapping = modelMapper.CompileMappingForAllExplicitlyAddedEntities(); 
    configuration.AddMapping(mapping); 
} 

我發現的是,在XML文件中的實體添加到配置,但不通過添加類代碼映射我。

關於我在做什麼的任何建議是錯誤的?

+0

如果你評論'configuration.AddAssembly(assembly);'它甚至會添加MbC類嗎? – Firo

回答

0

這是我用來做代碼你的願望:

private IHibernateConfigurationExtension m_ExtensionConfig; 
    private Configuration m_Configuration; 
    public Configuration Configuration 
    { 
     get 
     { 
      if (m_Configuration == null) 
      { 
       m_ExtensionConfig = FetchExtensionConfig(); 
       m_Configuration = new Configuration(); 
       string assemblyDirectory = Path.GetDirectoryName(m_ExtensionConfig.Assembly.Location); 
       m_Configuration.Configure(Path.Combine(assemblyDirectory, "hibernate.cfg.xml")); 
       m_Configuration = LoadHBMXML(m_Configuration); 
       m_Configuration = LoadMappings(m_Configuration); 
      } 
      return m_Configuration; 
     } 
    } 


    #region NHibernate Configuration 
    /// <summary> 
    /// Load the assemblies that are configured with the *.hbm.xml configuration 
    /// </summary> 
    /// <param name="configuration"></param> 
    /// <returns></returns> 
    private Configuration LoadHBMXML(Configuration configuration) 
    { 
     configuration.AddAssembly(m_ExtensionConfig.Assembly); 
     return configuration; 
    } 

    /// <summary> 
    /// Load the configurations that are configured with the ClassMap convention (NHibernate 3.2+) 
    /// </summary> 
    /// <param name="configuration"></param> 
    /// <returns></returns> 
    private Configuration LoadMappings(Configuration configuration) 
    { 
     // This configuration for mapper files 
     ModelMapper mapper = new ModelMapper(); 
     mapper.BeforeMapProperty += new PropertyMappingHandler(mapper_BeforeMapProperty); 
     List<Type> typeList = m_ExtensionConfig.Assembly.GetMatchingTypesInAssembly(item => m_ExtensionConfig.MappingsNamespace.Equals(item.Namespace)).ToList(); 
     mapper.AddMappings(typeList); 
     IEnumerable<HbmMapping> mappings = mapper.CompileMappingForEachExplicitlyAddedEntity(); 
     mappings.ForEach(m => configuration.AddMapping(m)); 
     if (DumpToXML) 
      mappings.WriteAllXmlMapping(); 
     return configuration; 
    } 

我用

/// <summary> 
/// An interface to be implemented within the assembly using the 
/// HibernateDAO class. This determines what gets configured 
/// for hibernate automatically. 
/// <para>NOTE: Currently only supports a single implementation 
/// within all loaded assemblies</para> 
/// </summary> 
public interface IHibernateConfigurationExtension 
{ 
    /// <summary> 
    /// The namespace containing the mapping files. 
    /// <para>Only a single namespace is currently supported</para> 
    /// </summary> 
    string MappingsNamespace { get; } 

    /// <summary> 
    /// The assembly to search for .hbm.xml hibernate configuration files 
    /// </summary> 
    Assembly Assembly { get; } 

    /// <summary> 
    /// Dictionary of conversion mappings 
    /// <para>Type is the object type, the type used in object definitions</para> 
    /// <para>Type of IUserType is the NHIbernate IUserType implementation to convert 
    /// between the Type and the persisted representation</para> 
    /// </summary> 
    IDictionary<Type, Type> UserConversionMappings { get; } 
} 

接口和方法來獲取擴展配置

/// <summary> 
    /// Fetch the class that implements the IHibernateConfigurationExtension interface 
    /// <para>Support is only provided for a single implementation of this class 
    /// through all loaded assemblies</para> 
    /// </summary> 
    /// <returns>The class that implements the extension</returns> 
    private IHibernateConfigurationExtension FetchExtensionConfig() 
    { 
     ICollection<Type> interfaces = AssemblyUtils.GetMatchingTypes(item => item.GetInterfaces().Contains(typeof(IHibernateConfigurationExtension))); 
     if (interfaces.Count == 0) 
      throw new ArgumentException("No implementation of IHibernateConfigurationExtension found"); 
     if (interfaces.Count > 1) 
      throw new ArgumentException("Only support for a single implementation if IHibernateConfigurationExtension available. Please raise support request"); 
     return Activator.CreateInstance(interfaces.First()) as IHibernateConfigurationExtension; 
    } 

而且AssemblyUtils中需要的部分

/// <summary> 
    /// Get all matching types in all assemblies that match the predicate 
    /// </summary> 
    /// <param name="predicate">The predicate function to match the types against</param> 
    /// <returns>The list of all types that match the predicate</returns> 
    public static ICollection<Type> GetMatchingTypes(Predicate<Type> predicate) 
    { 
     ICollection<Type> types = new List<Type>(); 
     foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) 
     { 
      try 
      { 
       types.AddRange(assembly.GetTypes().Where(i => i != null && predicate(i)).ToList()); 
      } 
      catch (ReflectionTypeLoadException ex) 
      { 
       types.AddRange(ProcessExceptionTypes(ex.Types, i => i != null && predicate(i))); 
      } 
     } 
     return types; 
    } 


    /// <summary> 
    /// Process each of the types in the list (usually called from within a ReflectionTypeLoadException 
    /// to load the types that match the predicate. 
    /// </summary> 
    /// <param name="theTypes">The list of types to process (taken from ReflectionTypeLoadException.Types</param> 
    /// <param name="predicate">The boolean predicate to compare the type against</param> 
    /// <returns>The collection of types (that can be loaded) matching the predicate</returns> 
    private static ICollection<Type> ProcessExceptionTypes(Type[] theTypes, Predicate<Type> predicate) 
    { 
     ICollection<Type> types = new List<Type>(); 
     foreach (Type theType in theTypes) 
     { 
      try 
      { 
       if (predicate(theType)) 
        types.Add(theType); 
      } 
      // This exception list is not exhaustive, modify to suit any reasons 
      // you find for failure to parse a single assembly 
      catch (BadImageFormatException) 
      { 
       // Type not in this assembly - reference to elsewhere ignored 
      } 
      catch (FileNotFoundException) 
      { 
       // Type not in this assembly - reference to elsewhere ignored 
      } 
     } 
     return types; 
    } 
+0

它缺少什麼是FetchExtensionConfig()和m_ExtensionConfig – Daniel

相關問題