2013-03-01 114 views
0

我使用自动映射与功能NHibernate,并用下面的代码,以确保NHibernate的不剥去毫秒时间戳列比较:LINQ查询与NHibernate的

public class TimestampTypeConvention : IPropertyConvention, IPropertyConventionAcceptance 
{ 
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Type == typeof(DateTime) || x.Type == typeof(DateTimeOffset)); 
    } 

    public void Apply(IPropertyInstance instance) 
    { 
     instance.CustomType<TimestampType>(); 
    } 
} 

这工作得很好,所以数据正确存储在数据库中。

然而,当我运行下面的LINQ查询,我没有得到一个比赛,我希望它:

bool isDuplicate = session.Query<TagData>() 
          .Any(x => x.TagName == message.EventTag.TagName 
           && x.TimeStamp == message.EventTag.TimeStamp.UtcDateTime); 

生成的SQL是这样的,并解释了为什么这不起作用:

select tagdata0_."Id" as column1_0_, tagdata0_."TagName" as column2_0_, 
tagdata0_."TimeStamp" as column3_0_, tagdata0_."Value" as column4_0_, 
tagdata0_."QualityTimeStamp" as column5_0_, tagdata0_."QualitySubstatus" as column6_0_, 
tagdata0_."QualityExtendedSubstatus" as column7_0_, tagdata0_."QualityLimit" as column8_0_, 
tagdata0_."QualityDataSourceError" as column9_0_, tagdata0_."QualityTagStatus" as column10_0_, 
tagdata0_."TagType" as column11_0_ from "TagData" tagdata0_ 
where tagdata0_."TagName"=:p0 and tagdata0_."TimeStamp"=:p1 limit 1; 
:p0 = 'VALVE_HW_CMD' [Type: String (0)], 
:p1 = 01.03.2013 16:51:30 [Type: DateTime (0)] 

如何强制生成的查询使用全精度?

BTW,message.EventTag.TimeStampDateTimeOffset

回答

0

我被记录输出上当:实际的SQL(从PostgreSQL的日志文件中取出的)看起来是这样的:

SELECT this_."Id" as column1_0_0_, this_."TagName" as column2_0_0_, 
this_."TimeStamp" as column3_0_0_, this_."Value" as column4_0_0_, 
this_."QualityTimeStamp" as column5_0_0_, this_."QualitySubstatus" as column6_0_0_, 
this_."QualityExtendedSubstatus" as column7_0_0_, this_."QualityLimit" as column8_0_0_, 
this_."QualityDataSourceError" as column9_0_0_, this_."QualityTagStatus" as column10_0_0_, 
this_."TagType" as column11_0_0_ FROM "TagData" this_ 
WHERE this_."TimeStamp" = ((E'2013-03-01 16:51:30.509498')::timestamp) 

这才是真正的原因,它没有像预期的那样工作:PostgreSQL中的timestamp列只有微秒精度,而DateTimeDiff这里的值是16:51:30.5094984,这意味着微秒精度的1/10。保持完全准确性的唯一方法似乎是将滴答储存在数据库中。

(另一个让我困惑的原因是,我在不同的线程上或多或少地同时收到来自MassTransit的重复消息,因此检查数据库重复数据当然并不总是有效的,O,多线程的奇迹!)