2010-08-04 87 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