重新水化流畅的 nhibernate 将 DateTime 配置为 Kind Utc 而不是 Unspecified

发布于 2024-08-06 20:00:44 字数 136 浏览 5 评论 0原文

有没有一种方法可以在流畅的nhibernate中映射DateTime来重新水合我的实体,并将DateTime.Kind设置为Utc而不是未指定?我目前坚持使用 Utc 的 DateTime,但返回的 Kind 始终是 Unspecified,浪费了我的时间。

Is there a way in fluent nhibernate to map a DateTime to rehydrate my entity with DateTime.Kind set to Utc rather than unspecified? I'm currently persisting a DateTime that is Utc, but the Kind coming back is always Unspecified, throwing off my time.

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

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

发布评论

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

评论(3

北音执念 2024-08-13 20:00:44

从 Nhibernate 3.0 开始,使用 FluentNHibernate,您可以执行以下操作:

Map(x => x.EntryDate).CustomType<UtcDateTimeType>();

不再需要使用拦截器。

As of Nhibernate 3.0, using FluentNHibernate, you can do the following:

Map(x => x.EntryDate).CustomType<UtcDateTimeType>();

No need to use interceptors anymore.

追我者格杀勿论 2024-08-13 20:00:44

这并不是 Fluent 所特有的,而是 NHibernate 映射的基础。我们使用拦截器来指定 Kind。它类似于此博客文章的方法< /a> 其中列出了几个替代方案。还有一个建议的补丁 (NH-1135) 用于本地处理 UtcDateTime 和 LocalDateTime。我鼓励你投票支持它。

public class InterceptorBase : EmptyInterceptor
{
    public override bool OnLoad(object entity, object id, object[] state,
        string[] propertyNames, IType[] types)
    {
        ConvertDatabaseDateTimeToUtc(state, types);
        return true;
    }

    private void ConvertDatabaseDateTimeToUtc(object[] state, IList<IType> types)
    {
        for (int i = 0; i < types.Count; i++)
        {
            if (types[i].ReturnedClass != typeof(DateTime))
                continue;

            DateTime? dateTime = state[i] as DateTime?;

            if (!dateTime.HasValue)
                continue;

            if (dateTime.Value.Kind != DateTimeKind.Unspecified)
                continue;

            state[i] = DateTime.SpecifyKind(dateTime.Value, DateTimeKind.Utc);
        }
    }
}

This isn't specific to fluent, but is fundamental to the NHibernate mapping. We use an interceptor to specify the Kind. It is similar to the approach in this blog post which lists a couple alternatives. There is also a proposed patch (NH-1135) for handling UtcDateTime and LocalDateTime natively. I'd encourage you to vote for it.

public class InterceptorBase : EmptyInterceptor
{
    public override bool OnLoad(object entity, object id, object[] state,
        string[] propertyNames, IType[] types)
    {
        ConvertDatabaseDateTimeToUtc(state, types);
        return true;
    }

    private void ConvertDatabaseDateTimeToUtc(object[] state, IList<IType> types)
    {
        for (int i = 0; i < types.Count; i++)
        {
            if (types[i].ReturnedClass != typeof(DateTime))
                continue;

            DateTime? dateTime = state[i] as DateTime?;

            if (!dateTime.HasValue)
                continue;

            if (dateTime.Value.Kind != DateTimeKind.Unspecified)
                continue;

            state[i] = DateTime.SpecifyKind(dateTime.Value, DateTimeKind.Utc);
        }
    }
}
錯遇了你 2024-08-13 20:00:44

由于@DPeden的回答,以及@Ricardo_Stuven的评论似乎有点混乱,我想我会构建这个例子:

具有:

Map(x => x.EntryDate).CustomType<LocalDateTimeType>();

与具有相同:(此代码旨在说明,它不是示例)

Map(x => x._hiddenEntryDate).Column("EntryDate");
Ignore(x => x.EntryDate);

///...

public class MyEntity
{
    protected virtual DateTime _hiddenEntryDate { get; set; }
    public DateTime EntryDate
    {
        get
        {
            return DateTime.SpecifyKind(_hiddenEntryDate, DateTimeKind.Local);
        }
        set
        {
            _hiddenCreated = DateTime.SpecifyKind(value, DateTimeKind.Local);
        }
    }
}

也就是说,它永远不会调用 .ToLocalTime(),无论您传递给它或从中取出什么,都假定代表本地时间,但并不强制如此,它无法识别开发人员是否会正确使用 DateTimeKind。

同样,UtcDateTimeType 永远不会调用 .ToUniversalTime()

Due to @DPeden's answer, and the comment by @Ricardo_Stuven seeming to have slight confusion, I thought I would construct this example:

Having:

Map(x => x.EntryDate).CustomType<LocalDateTimeType>();

Is the same as having: (This code is meant to be illustrative, it is NOT an example to follow)

Map(x => x._hiddenEntryDate).Column("EntryDate");
Ignore(x => x.EntryDate);

///...

public class MyEntity
{
    protected virtual DateTime _hiddenEntryDate { get; set; }
    public DateTime EntryDate
    {
        get
        {
            return DateTime.SpecifyKind(_hiddenEntryDate, DateTimeKind.Local);
        }
        set
        {
            _hiddenCreated = DateTime.SpecifyKind(value, DateTimeKind.Local);
        }
    }
}

Namely, it NEVER calls .ToLocalTime(), whatever you pass into it, or get out of it, is assumed to represent localtime, it is not enforced to be, it does not recognize that the developer would ever use DateTimeKind correctly.

Similarly UtcDateTimeType never calls .ToUniversalTime()

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