2011-01-10 50 views
0

似乎存在失配betweeen通過NHibernate和SQL生成的SQL在以下情況下,由SQL2008預期:包含和SubString的Linq到Nhibernate不起作用?

public void PersistPerson() 
    { 
     var sessionFactory = CreateSessionFactory(); 
     using (var session = sessionFactory.OpenSession()) 
     { 
      using(var transaction = session.BeginTransaction()) 
      { 
       session.Save(new Person {FirstName = "Foo", LastName = "Bar"}); 
       session.Save(new Person {FirstName = "Foo", LastName = "Dah"}); 
       session.Save(new Person {FirstName = "Foo", LastName = "Wah"}); 
       transaction.Commit(); 
      } 
     } 
     using (var session = sessionFactory.OpenSession()) 
     { 
      using(var transaction = session.BeginTransaction()) 
      { 
       var queryable = from p in session.Query<Person>() select p; 
       var lastNames = new[]{"B", "D"}; 
       var result = queryable.Where(r => lastNames.Contains(r.LastName.Substring(0, 1))).ToList(); 
       transaction.Commit(); 

       Assert.That(result[0].LastName, Is.EqualTo("Bar")); 
      } 
     } 
    } 

通過NHibernate的產生得到的SQL查詢

var result = queryable.Where(r => lastNames.Contains(r.LastName.Substring(0, 1))).ToList(); 

是:

select person0_.Id  as Id0_, 
    person0_.FirstName as FirstName0_, 
    person0_.LastName as LastName0_ from [Person] person0_ where upper(substring(person0_.LastName, 
        0 /* @p0 */, 
        1 /* @p1 */)) in ('B' /* @p2 */) 

從T-SQL的MSDN文檔SUBSTRING http://msdn.microsoft.com/en-us/library/ms187748.aspx SUBSTRING(value_expression,start_expression,length_expression)

雖然文檔說,否則,從註釋張貼start_expression似乎是1 - 基(不是0索引)

例如: SQL:選擇x = SUBSTRING( 'abcdef',0,3); 結果:x ='ab' 和NOT x ='abc'

有關如何解決此問題的任何想法?

回答

0

我認爲這是一個錯誤。只需將您的代碼更改爲r.LastName.Substring(1, 1)並且它可以工作(生成的sql將是子字符串(1,1))。

+0

我使用InMemory List AsQueryable用於單元測試此功能,並在生產中將內存實現與NHQueryable API交換。針對內存列表運行的單元測試失敗。我試圖解決這個問題 – 2011-01-11 19:48:37