2012-08-09 57 views
2

我使用NH 3.3.1.4000与Oracle 10g和SQL Server 2008.NHibernate用连字符查询缓存错误

我最近遇到了这个可能的错误。考虑以下两个查询:

var query1 = session.Query<Content>().Cacheable() 
        .Where(c => c.Name == "test-test").ToList(); 

var query2 = session.CreateQuery("from Content c where c.Name = :name") 
        .SetString("name", "test-test") 
        .SetCacheable(true); 
var list = query.List<Content>(); 

无论是上述查询会产生下面的SQL查询之一:

select content0_.Id  as Id6_,  
content0_.Name as Name6_,  
from Content content0_ 
where content0_.Name = '' 

传递进来,并且具有任何参数“ - ”(连字符),没有按如果我删除参数中的.Cacheable或SetCacheable()或“ - ”,它可以正常工作。 在我开始查看NH源代码之前有任何解决方法的建议? 谢谢。

UPDATE 我可以确认SQL Server也存在同样的问题。我猜测它与数据库无关,而与查询缓存无关。 我应该提到,在第一次运行查询之前,发生缓存之前,生成的查询是正确的。但是当我第二次运行相同的查询时,这次从查询缓存中加载,用连字符缓存不起作用。请参阅我在.NET MVC应用程序上使用SQL Server 2008运行的以下测试。

var test1 = session.Query<Student>().Cacheable().Where(c => c.Firstname == "first-name").ToList(); 

var test2 = session.Query<Student>().Where(c => c.Firstname == "first-name").ToList(); 

var test3 = session.Query<Student>().Cacheable().Where(c => c.Firstname == "firstname").ToList(); 

我第一次加载生成以下查询页面,都是正确的:

-- statement #1 
select student0_.Id  as Id1_, 
    student0_.Firstname as Firstname1_, 
    student0_.Lastname as Lastname1_ 
from Students student0_ 
where student0_.Firstname = 'first-name' 

-- statement #2 
select student0_.Id  as Id1_, 
    student0_.Firstname as Firstname1_, 
    student0_.Lastname as Lastname1_ 
from Students student0_ 
where student0_.Firstname = 'first-name' 

-- statement #3 
select student0_.Id  as Id1_, 
    student0_.Firstname as Firstname1_, 
    student0_.Lastname as Lastname1_ 
from Students student0_ 
where student0_.Firstname = 'firstname' 

但我重新载入网页后,让查询缓存做它的东西,我得到以下三个查询:

-- statement #1 
Cached query: 
select student0_.Id  as Id1_, 
    student0_.Firstname as Firstname1_, 
    student0_.Lastname as Lastname1_ 
from Students student0_ 
where student0_.Firstname = '' 

-- statement #2 
select student0_.Id  as Id1_, 
    student0_.Firstname as Firstname1_, 
    student0_.Lastname as Lastname1_ 
from Students student0_ 
where student0_.Firstname = 'first-name' 

-- statement #3 
Cached query: 
select student0_.Id  as Id1_, 
    student0_.Firstname as Firstname1_, 
    student0_.Lastname as Lastname1_ 
from Students student0_ 
where student0_.Firstname = 'firstname' 

正如您所看到的,第二次在语句#1中该参数为空。语句#1和语句#2之间的唯一区别是使用查询缓存。只要参数中没有“ - ”连字符,缓存查询就可以在第二次加载(test3)中正常工作。

+0

这两个查询都会在SQL Server上生成正确的结果(我没有Oracle方便)。你真的确定那些是你传递的价值吗?这没有多大意义。 – 2012-08-10 18:06:30

+0

即使数据库是SQL Server,也存在此问题。当您第一次加载数据时,它可以正常工作,但是第二次加载数据(从查询缓存中)问题很明显。请参阅上面的更新与实际查询。 – 2012-08-11 05:41:51

+0

这没有意义。如果您正在缓存,则第二次完全没有查询。 – 2012-08-11 12:28:41

回答

0

看来这肯定是NHibernate Profiler中的一个bug,而不是NHibernate或查询缓存。我已经能够使用包含连字符的参数重现您的问题,以便在探查器中显示为空字符串的缓存查询。

虽然我在测试中总是得到正确的结果集。为记录器NHibernate.Cache.StandardQueryCache启用调试级别还表示查询缓存永远不会看到这些空字符串参数,而是带有连字符的实际参数值。

我的结论是,在列出缓存查询时,分析器不正确地显示这些参数。