c# - Fluent NHibernate - 从 SQL 转换为 C# 类型时如何进行附加处理?

标签 c# nhibernate orm fluent-nhibernate type-conversion

我使用 Fluent NHibernate 作为数据访问层,每次将 SQL 中的值映射到 DateTime 类型时都需要执行此操作:

var newDateTime = DateTime.SpecifyKind(oldDateTime, DateTimeKind.Local);

在上面的代码中,newDateTime 表示所有 SQL 到 C# 转换应返回的值,oldDateTime 表示 NHibernate 的默认转换器自动转换为的值。

除了 Fluent NHibernate 文档非常黯淡的问题之外,我尝试在互联网上搜索可以让我做到这一点的约定,但是 IUserType 太重了(而且我还没有找到全面的解释如何实现从 IUserType 派生的方法),而 IPropertyConvention 似乎只提供修改 C# 如何转换为 SQL 的方法(而不是相反,这正是我在这种情况下需要的)。

有人可以给我指出正确的方向吗?和/或提供一些高质量的链接来阅读约定?维基页面没有详细解释任何内容,因此请不要链接这些页面。谢谢。

最佳答案

NHibernate(不仅是Fluent)支持设置,区分如何处理存储在DB中的DateTime(不管某些DB是否支持偏移量,例如datetimeoffset (Transact-SQL))。请参阅5.2.2. Basic value types

从数据库获取:

因此,我们可以显式定义如何处理从表列返回的值,如下所示:

Map(x => x.ExpiryDate).CustomType<UtcDateTimeType>(); // UTC
Map(x => x.MaturityDate).CustomType<LocalDateTimeType>(); // local

因此,一旦从数据库检索,所有 DateTime 属性将自动提供正确的 Kind设置:

Assert.IsTrue(entity.ExpiryDate.Kind == DateTimeKind.Utc);
Assert.IsTrue(entity.MaturityDate.Kind == DateTimeKind.Local);

设置

让我提供一些摘录自 Date/Time Support in NHibernate :

Notice that NHibernate did not perform any conversions or throw an exception when saving/loading a DateTime value with the wrong DateTimeKind. (It could be argued that NHibernate should throw an exception when asked to save a Local DateTime and the property is mapped as a UtcDateTime.) It is up to the developer to ensure that the proper kind of DateTime is in the appropriate field/property.

换句话说,实体 DateTime ,来自客户端(在绑定(bind)、反序列化等期间)必须在自定义==我们的代码中正确设置。

Web API 中从 JSON 转换 DateTime 的示例。虽然 JSON 是 UTC,但 DB 设置为 lcoal。我们可以注入(inject)这个转换器并确保:

class DateTimeConverter : IsoDateTimeConverter
{
    public DateTimeConverter()
    {
        DateTimeStyles = DateTimeStyles.AdjustToUniversal;
    }

    public override object ReadJson(JsonReader reader, Type objectType
           , object existingValue, JsonSerializer serializer)
    {
        var result = base.ReadJson(reader, objectType, existingValue, serializer);
        var dateTime = result as DateTime?;
        if (dateTime.Is() && dateTime.Value.Kind == DateTimeKind.Utc)
        {
            return dateTime.Value.ToLocalTime();
        }
        return result;
    }

现在我们可以确定:

  1. GET - 我们的映射 .CustomType<LocalDateTimeType>()将正确通知应用程序来自数据库的数据位于本地区域
  2. SET - 转换器,将正确设置本地区域的日期时间值

关于c# - Fluent NHibernate - 从 SQL 转换为 C# 类型时如何进行附加处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18601306/

相关文章:

c# - 如何使用linq获取根节点属性值

.net - 如何使 NHibernate 缓存获取的子集合?

visual-studio - 为什么在运行我的应用程序时会遗漏一些引用?

java - Hibernate - 无法在 where 子句中使用 UserType 执行查询

php - Kohana ORM,在模型中定义字段

c# - 无法转换为我的自定义 ConfigurationSection

javascript - 从 iPad 创建 Canvas 图像

c# - 如何调试随机崩溃?

linq - LINQ 中的 IsNull 或合并功能?

java - 如何更新@OneToMany 集合中的现有条目?