2009-02-04 2 views
0

내 응용 프로그램은 Oracle과 MS SQL 데이터베이스를 모두 지원하며 약간 다른 스키마가 각각 구현되었습니다. 내가 한 가지 문제는 MS SQL에서 자동 증가 기본 키가 있지만 Oracle에서 수동 삽입 기본 키가있는 클래스입니다. 지금 NHibernate는 임베디드 리소스를 사용하는 프로그래밍 방식의 매핑 파일을로드합니다.

, 같은 클래스 모양의 두 개의 서로 다른 매핑 :

오라클 :

<class lazy="false" name="EntityPropertyName" table="entity_property_name" > 
<id name="ID" column="id" type="Int32" unsaved-value="-1"> 
    <generator class="increment" /> 
</id> 
<property name="Name" column="name"/> 

MS SQL :

<class lazy="false" name="EntityPropertyName" table="entity_property_name" > 
<id name="ID" column="id" type="Int32" unsaved-value="-1"> 
    <generator class="native"> 
    </generator> 
</id> 
<property name="Name" column="name"/> 

T 그의 매핑 파일을 다른 매핑 파일에 넣을 수 있고 런타임에 올바른 파일을로드 할 수 있기 때문에 그의 세계에서 가장 나쁜 것은 아닙니다.

NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration(); 

      if (newDBType == CompanyName.AppName.Data.Enum.DatabaseType.MsSqlServer) 
      { 
       cfg.Properties["dialect"] = "NHibernate.Dialect.MsSql2000Dialect"; 
       cfg.Properties["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver"; 
       cfg.AddFile("DataTypes\\MSSQLTypes.hbm.xml"); 
      } 
      else 
      { 
       cfg.Properties["dialect"] = "NHibernate.Dialect.Oracle9Dialect"; 
       cfg.Properties["connection.driver_class"] = "NHibernate.Driver.OracleClientDriver"; 
       cfg.AddFile("DataTypes\\OracleTypes.hbm.xml"); 
      } 

      cfg.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider"; 

      cfg.Properties["connection.connection_string"] = connectionString; 

      cfg.AddAssembly("CompanyName.AppName.Data"); 

      Sessions = cfg.BuildSessionFactory(); 

나는이 전략에 대해 싫어하는 것은

하지만 지금은 거기에있을 필요하거나 응용 프로그램이 작동하지 않습니다 내 프로그램의 bin 디렉토리에 못생긴 XML 파일을 가지고있다. 주 매핑 파일로 할 수있는 것처럼 다른 파일을 리소스에 포함 할 수 있다면 런타임에 각 파일을로드할지 여부를 선택하는 것이 훨씬 더 좋습니다.

문제를 해결할 수있는 방법이 있습니까? 아니면 다른 방법일까요?


편집 : 감사합니다. Cristian! 당신은 질문을 이해했는데, 나는 그런 리소스가 NHibernate에 의해로드 될 수 있다는 것을 인식하지 못했습니다. 그것에 대해 생각해 보면 AddAssembly 메소드가 찾은 리소스를 열거하고로드하는 방법이 있어야한다는 것이 합리적이라고 생각합니다!

NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration(); 

      if (newDBType == CompanyName.AppName.Data.Enum.DatabaseType.MsSqlServer) 
      { 
       cfg.Properties["dialect"] = "NHibernate.Dialect.MsSql2000Dialect"; 
       cfg.Properties["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver"; 
       cfg.AddInputStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("CompanyName.AppName.Data.DataTypes.MSSQLTypes.hbm.xml")); 
      } 
      else 
      { 
       cfg.Properties["dialect"] = "NHibernate.Dialect.Oracle9Dialect"; 
       cfg.Properties["connection.driver_class"] = "NHibernate.Driver.OracleClientDriver"; 
       cfg.AddInputStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("CompanyName.AppName.Data.DataTypes.OracleTypes.hbm.xml")); 
      } 

      cfg.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider"; 

      cfg.Properties["connection.connection_string"] = connectionString; 

      cfg.AddInputStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("CompanyName.AppName.Data.DataTypes.Types.hbm.xml")); 

      Sessions = cfg.BuildSessionFactory(); 

답변

2

나는 당신의 중요한 포인트를 누락 될 수 있습니다 :

내 솔루션의 존재를했다. Hibernate는 매핑 파일을 어떻게 공급할 수 있는지에 대해 매우 유연하다. 예 :

cfg.AddInputStream(assembly.GetManifestResourceStream("MyNamespace.MyEmbeddedresource.hbm.xml")); 

또는 사용자 정의 내장 XML 문자열

:

cfg.AddXml(myCustomBuildXmlString); 

또한 프로그램에 직접 매핑을 추가 할 수 있지만 조금 복잡합니다.