使用Contains和SubString的Linq到Nhibernate不起作用?

时间:2011-01-10 22:09:49

标签: tsql substring linq-to-nhibernate

在下列情况下,NHibernate生成的SQL与SQL2008预期的SQL之间似乎存在不匹配:

    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 SUBSTRING的MSDN文档 http://msdn.microsoft.com/en-us/library/ms187748.aspx  SUBSTRING(value_expression,start_expression,length_expression)

虽然文档另有说明,但发布的评论中start_expression似乎是基于1的(不是0索引)

例如: SQL:SELECT x = SUBSTRING('abcdef',0,3); 结果:x ='ab' 而不是x ='abc'

关于我如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:0)

我认为这是一个错误。只需将您的代码更改为r.LastName.Substring(1, 1)并且它可以正常工作(生成的sql将是子字符串(1,1))。