2010-08-04 53 views
1

我需要動態添加命名查詢到NHibernate配置對象。搜索引擎返回幾個引用NamedSQLQueryDefinition或NamedQueryDefinition的命中。以下是我正在嘗試做的事情。我不知道如何提供給NamedSQLQueryDefinition構造函數來成功創建查詢。任何人都可以提供一個如何以正確的方式創建新的NamedSQLQueryDefinition的示例嗎?謝謝!!如何將NamedSQLQueryDefinition類動態用作sql查詢等效項?

會話初始化:

private static ISessionFactory CreateSessionFactory() 
    { 
     var configuration = new Configuration(); 

     return Fluently.Configure(configuration.Configure()) 
      .ExposeConfiguration(AddQueries) 
      .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>()) 
      .Mappings(m => m.HbmMappings.AddFromAssemblyOf<Program>()) 
      .BuildConfiguration() 
      .BuildSessionFactory(); 
    } 

的AddQueries會是這個樣子:

private static void AddQueries(Configuration cfg) 
    { 
     var nameQuery = new NamedSQLQueryDefinition("exec pr_GETCustomer ?", ...) 

     cfg.NamedSQLQueries.Add("pr_GETCustomer", nameQuery); 
     var cust = cfg.GetClassMapping(typeof (Customer)); 

     cust.LoaderName = "pr_GETCustomer"; 
    } 

PS:我想這條路線,因爲功能NHibernate沒有實現的方式來配置裝載機&來自hbm文件的sql-query元素。

回答

1

AddQueries方法將按如下實現,以「修復」Fluent NHibernate缺乏Loader支持。訣竅是正確設置INativeSQLQueryReturn []值以包含從表列到實體屬性的映射。它應該模擬HBM文件中返回sql-query元素的內容,其中定義了類(具有名稱空間)和屬性映射(請參見下面的XML)。感謝@ jimbobmcgee讓我開始朝這個方向發展!

private static void AddQueries(Configuration cfg) 
{ 
    var namedQuery = new NamedSQLQueryDefinition(
     "exec dbo.pr_GETCustomers @CustomerID=?", 
     new INativeSQLQueryReturn[] 
      { 
       new NativeSQLQueryRootReturn(
        "Customers", 
        "VehicleInfo.Entities.Customers", 
        new Dictionary<string, string[]> 
         { 
            {"CustomerID", new[] {"CustomerID"}}, 
            {"CompanyName", new[] {"CompanyName"}} 
        }, 
        LockMode.Read) 
      }, 
     new List<string> { "dbo.Customers" }, 
     true, 
     null, 
     15, 
     1000, 
     FlushMode.Auto, 
     CacheMode.Normal, 
     false, 
     "", 
     null, 
     true); 

    cfg.NamedSQLQueries.Add("pr_GETCustomers", namedQuery); 
    var cust = cfg.GetClassMapping(typeof(Customers)); 

    cust.LoaderName = "pr_GETCustomers"; 
} 

樣品HBM文件做同樣的事情:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
    default-access="property" auto-import="true" 
    default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" 
     mutable="true" name="VehicleInfo.Entities.Customers, VehicleInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Customers"> 
     <id name="CustomerID" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
      <column name="CustomerID" /> 
      <generator class="assigned" /> 
     </id> 

     <property name="CompanyName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
      <column name="CompanyName" /> 
     </property> 

     <loader query-ref="pr_GETCustomers"/> 

     <sql-insert callable="true" check="none">exec dbo.pr_INSERTCustomers @CompanyName=?, @CustomerID=?</sql-insert> 
     <sql-update callable="true" check="none">exec dbo.pr_UPDATECustomers @CompanyName=?, @CustomerID=?</sql-update> 
     <sql-delete callable="true" check="none">exec dbo.pr_DELETECustomers @CustomerID=?</sql-delete> 
    </class> 
    <sql-query name="pr_GETCustomers"> 
     <return alias="cust" class="VehicleInfo.Entities.Customers, VehicleInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
      <return-property name="CustomerID" column="CustomerID"></return-property> 
      <return-property name="CompanyName" column="CompanyName"></return-property> 
     </return> 
     exec dbo.pr_GETCustomers @CustomerID=? 
    </sql-query> 
</hibernate-mapping> 
0

我對此很新,但大部分參數都是可以從HBM文件中提供的屬性確定的。這就是說,我不太確定QuerySpaces是什麼。我有什麼,我認爲你正在努力實現最接近的是使用以下(未經測試):

ISQLQuery q = session.CreateSQLQuery("exec pr_GETCustomer :p1"); 

if (q is SqlQueryImpl) 
{ 
    IDictionary<string, TypedValue> namedParams = new Dictionary<string, TypedValue>(); 
    namedParams.Add("p1", new TypedValue(NHibernateUtil.Int32, 12345); 

    IDictionary<string, string> paramTypes = new Dictionary<string, string>(); 

    NativeSQLQuerySpecification spec = 
     (q as SqlQueryImpl).GenerateQuerySpecification(namedParams); 

    NativeSQLQueryDefiniton def = new NativeSQLQueryDefiniton(
     spec.QueryString, 
     spec.SqlQueryReturns, 
     spec.QuerySpaces, 
     false, 
     null, 
     -1, 
     -1, 
     FlushMode.Never, 
     CacheMode.Normal, 
     true, 
     "blah", 
     paramTypes, 
     false 
    ); 
} 

很顯然,我不喜歡投給SqlQueryImpl。我希望,一旦我們中的一個人完成了一次,可以理解像querySpaces這樣的混淆屬性,所以你不必這樣做。

並不是說我期望它100%的工作,但從這裏可能更容易實現。

+0

謝謝,我會嘗試這種方法。我還試圖弄清楚QuerySpaces是什麼,並且不想挖掘NHibernate源代碼。 – 2010-08-10 13:13:36