NHibernate Postgresql 日期时间到时间转换

发布于 2024-11-09 17:19:36 字数 748 浏览 3 评论 0原文

我使用 Fluent NHibernate 来配置我的映射,在读取数据时一切正常,但在尝试插入或更新具有 Postgresql 时间类型的记录时,我收到错误消息

"ERROR: 42804: column \"run_time\" is类型为带时区的时间,但表达式为不带时区的时间戳类型”

看起来 NHibernate 可能会对将 DateTime 转换为哪个 DbType 感到困惑,如您从 PostgreSQL 和 C# 数据类型,DateTime 映射到多种 DbType。

我还尝试从 IUserType 为该列指定自定义类型,但在 NullSafeSet 覆盖上我得到 NullReferenceError

public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
    var obj = (DateTime)value;

    NHibernate.NHibernateUtil.Time.NullSafeSet(cmd, obj, index);
}

是否有某种类型的提示我可以提供告诉 NHibernate 将 DateTime 转换为 Postgresql“时间”类型?或者我可以通过 IUserType 来实现这一点,而我只是做错了什么?

I'm using Fluent NHibernate to configure my mappings everything works when reading data but when trying to insert or update records that have a Postgresql type of Time I get the error message

"ERROR: 42804: column \"run_time\" is of type time with time zone but expression is of type timestamp without time zone"

It looks like NHibernate might be confused on which DbType to convert the DateTime to as you can see from PostgreSQL and C# Datatypes that there are several DbTypes that DateTime map to.

I also tried specifying a custom type for this column from IUserType but on the NullSafeSet override I get a NullReferenceError

public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
    var obj = (DateTime)value;

    NHibernate.NHibernateUtil.Time.NullSafeSet(cmd, obj, index);
}

Is there some type of hint I can provide to either tell NHibernate to convert the DateTime to a Postgresql "time" type? Or can I achieve this by the IUserType and I'm just doing something wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一个人的夜不怕黑 2024-11-16 17:19:36

想通了!

显然,我链接的转换表要么是错误的,要么是过时的。事实证明,Npgsql 需要 System.TimeSpan 对象来正确转换为 Postgresql“时间”对象。我觉得奇怪的是,他们试图将代表两个时间之间差异的东西转换为我们所认为的 HH:mm:ss,但事实就是如此。

我没有将 RunTime 属性的类型从 System.DateTime 更改为 System.TimeSpan,而是创建了一个自定义 IUserType 并重写了 NullSafeSet ,使其看起来像

public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
    var obj = (DateTime)value;

    ((IDbDataParameter) cmd.Parameters[index]).Value = new TimeSpan(0, obj.Hour, obj.Minute, obj.Second);
}

Figured it out!

Apparently the conversion sheet I linked to is either wrong or out of date. It turns out that a System.TimeSpan object is what's needed for Npgsql to do a proper conversion to a Postgresql "time" object. It seems odd to me that they would try to convert something that represents a difference between two time's into what we think of as HH:mm:ss but that's the way it is.

Rather than change the type of my RunTime property from System.DateTime to System.TimeSpan I've instead created a custom IUserType and have overriden NullSafeSet to look like

public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
    var obj = (DateTime)value;

    ((IDbDataParameter) cmd.Parameters[index]).Value = new TimeSpan(0, obj.Hour, obj.Minute, obj.Second);
}
挽梦忆笙歌 2024-11-16 17:19:36

您可以通过如下定义映射来解决此问题:

Map(x => x.RunTime, "run_time").CustomSqlType("time");

You might be able to fix this issue by defining your mapping like this:

Map(x => x.RunTime, "run_time").CustomSqlType("time");
情域 2024-11-16 17:19:36

如果您认为 NH 对数据类型的定义无效,您可以在此处报告:
https://nhibernate.jira.com/browse/NH
+ 同时你可以驱动自己的方言来解决这个问题。像这样:

public class CustomDialect : OriginalDialect
{
    public CustomDialect()
    {
      //... add your new definitions here to override default values    
    }
}

现在你可以这样使用它:

var dbType = XyzConfiguration.Standard
                       ...
                       .Dialect<CustomDialect>();

If you think NH has invalid definitions for data types, you can report them here:
https://nhibernate.jira.com/browse/NH
+ in the mean time you can drive your own dialect to solve that. something like:

public class CustomDialect : OriginalDialect
{
    public CustomDialect()
    {
      //... add your new definitions here to override default values    
    }
}

now you can use it this way:

var dbType = XyzConfiguration.Standard
                       ...
                       .Dialect<CustomDialect>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文