0

Fluent NHibernateで自動マッピングを使用しており、次のコードを使用して、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)]

生成されたクエリに完全な精度を使用させるにはどうすればよいですか?

ところで、message.EventTag.TimeStampDateTimeOffset

4

1 に答える 1

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を意味します。完全な精度を維持する唯一の方法は、目盛りをデータベースに保存することだと思われます。

(私の混乱のもう1つの理由は、MassTransitから重複メッセージを多かれ少なかれ同時に異なるスレッドで受信したため、DBの重複チェックが常に機能するとは限りませんでした。O、マルチスレッドの驚異です!)

于 2013-03-02T11:25:54.477 に答える