Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fluent NHibernate-从SQL转换为C#类型时如何进行额外处理?_C#_Nhibernate_Orm_Fluent Nhibernate_Type Conversion - Fatal编程技术网

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

Fluent NHibernate-从SQL转换为C#类型时如何进行额外处理?,c#,nhibernate,orm,fluent-nhibernate,type-conversion,C#,Nhibernate,Orm,Fluent Nhibernate,Type Conversion,我使用Fluent NHibernate作为数据访问层,每次SQL中的值映射到DateTime类型时,我都需要这样做: var newDateTime = DateTime.SpecifyKind(oldDateTime, DateTimeKind.Local); 在上面的代码中,newDateTime表示所有SQL到C的转换应返回的值,oldDateTime表示NHibernate的默认转换器自动转换为的值 除了流畅的NHibernate文档非常糟糕这一问题之外,我还尝试在互联网上搜索允许我

我使用Fluent NHibernate作为数据访问层,每次SQL中的值映射到DateTime类型时,我都需要这样做:

var newDateTime = DateTime.SpecifyKind(oldDateTime, DateTimeKind.Local);
在上面的代码中,newDateTime表示所有SQL到C的转换应返回的值,oldDateTime表示NHibernate的默认转换器自动转换为的值

除了流畅的NHibernate文档非常糟糕这一问题之外,我还尝试在互联网上搜索允许我这样做的约定,但是IUserType太重了(我还没有找到如何实现从IUserType派生的方法的全面解释),而IPropertyConvention似乎只提供了修改C#如何转换为SQL的方法(而不是反过来,这正是我在本场景中需要的)

有人能给我指一下正确的方向吗?和/或提供一些高质量的链接来阅读公约?没有一个wiki页面详细解释了任何内容,所以请不要链接这些页面。谢谢。

NHibernate(不仅仅是Fluent)支持设置,区分如何处理存储在DB中的日期时间(不管某些DB对偏移量的支持,例如)。看

从数据库获取:

因此,我们可以明确定义,如何像这样处理从表列返回的值:

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

让我提供一些摘录:

请注意,NHibernate没有执行任何转换或抛出 保存/加载日期时间值时出现异常 DateTimeKind。(可以说NHibernate应该抛出 当要求保存本地日期时间且属性为 映射为UtcDateTime。)由开发人员确保 适当类型的日期时间位于适当的字段/属性中

换句话说,来自客户机的实体
DateTime
(在绑定、反序列化等过程中)必须在custom==我们的代码中正确设置

例如,在Web API中,从JSON转换日期时间期间。JSON为UTC时,DB设置为lcoal。我们可以注入此转换器并确保:

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;
    }
现在我们可以确定:

  • GET-我们的映射
    .CustomType()
    将正确地通知应用程序来自DB的数据位于本地区域
  • SET-转换器将正确地将日期时间值设置为本地区域
  • NHibernate(不仅仅是Fluent)支持设置,区分如何处理存储在DB中的日期时间(不管某些DB对偏移量的支持,例如)。看

    从数据库获取:

    因此,我们可以明确定义,如何像这样处理从表列返回的值:

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

    让我提供一些摘录:

    请注意,NHibernate没有执行任何转换或抛出 保存/加载日期时间值时出现异常 DateTimeKind。(可以说NHibernate应该抛出 当要求保存本地日期时间且属性为 映射为UtcDateTime。)由开发人员确保 适当类型的日期时间位于适当的字段/属性中

    换句话说,来自客户机的实体
    DateTime
    (在绑定、反序列化等过程中)必须在custom==我们的代码中正确设置

    例如,在Web API中,从JSON转换日期时间期间。JSON为UTC时,DB设置为lcoal。我们可以注入此转换器并确保:

    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;
        }
    
    现在我们可以确定:

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

  • 我最终使用IUserType实现了一个新的用户类型。事实上,我发现了一种新方法,可以最大限度地减少为不可变类型实现新用户类型所需的工作量,因为在扩展不可变类型(如DateTime)时,只有少数成员真正需要实现。这是我的密码:

    [Serializable]
    public class DateTimeKindLocalType : BaseImmutableUserType<DateTime>
    {
        public override object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            //This is the line that I needed
            return DateTime.SpecifyKind((DateTime)NHibernateUtil.DateTime2.NullSafeGet(rs, names), DateTimeKind.Local);
        }
    
        public override void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            NHibernateUtil.DateTime2.NullSafeSet(cmd, value, index);
        }
    
        public override SqlType[] SqlTypes
        {
            get { return new[] {NHibernateUtil.DateTime2.SqlType}; }
        }
    }
    
    [Serializable]
    public class DateTimeKindLocalTypeConvention
        : UserTypeConvention<DateTimeKindLocalType>
    {
    }
    
    [Serializable]
    public class DateTimeKindLocalNullableType : BaseImmutableUserType<DateTime?>
    {
        public override object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            if (owner == null)
                return null;
            return DateTime.SpecifyKind((DateTime)NHibernateUtil.DateTime2.NullSafeGet(rs, names), DateTimeKind.Local);
        }
    
        public override void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            NHibernateUtil.DateTime2.NullSafeSet(cmd, value, index);
        }
    
        public override SqlType[] SqlTypes
        {
            get { return new[] { NHibernateUtil.DateTime2.SqlType }; }
        }
    }
    
    [Serializable]
    public class DateTimeKindLocalNullableTypeConvention
        : UserTypeConvention<DateTimeKindLocalNullableType>
    {
    }
    
    
    [Serializable]
    public abstract class BaseImmutableUserType<T> : IUserType
    {
        public abstract object NullSafeGet(IDataReader rs, string[] names, object owner);
        public abstract void NullSafeSet(IDbCommand cmd, object value, int index);
        public abstract SqlType[] SqlTypes { get; }
    
        public new bool Equals(object x, object y)
        {
            if (ReferenceEquals(x, y))
            {
                return true;
            }
    
            if (x == null || y == null)
            {
                return false;
            }
    
            return x.Equals(y);
        }
    
        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }
    
        public object DeepCopy(object value)
        {
            return value;
        }
    
        public object Replace(object original, object target, object owner)
        {
            return original;
        }
    
        public object Assemble(object cached, object owner)
        {
            return DeepCopy(cached);
        }
    
        public object Disassemble(object value)
        {
            return DeepCopy(value);
        }
    
        public Type ReturnedType
        {
            get { return typeof(T); }
        }
    
        public bool IsMutable
        {
            get { return false; }
        }
    }
    

    如果有问题,请告诉我,我会尽快回答。

    我最终使用IUserType实现了一个新的用户类型。事实上,我发现了一种新方法,可以最大限度地减少为不可变类型实现新用户类型所需的工作量,因为在扩展不可变类型(如DateTime)时,只有少数成员真正需要实现。这是我的密码:

    [Serializable]
    public class DateTimeKindLocalType : BaseImmutableUserType<DateTime>
    {
        public override object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            //This is the line that I needed
            return DateTime.SpecifyKind((DateTime)NHibernateUtil.DateTime2.NullSafeGet(rs, names), DateTimeKind.Local);
        }
    
        public override void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            NHibernateUtil.DateTime2.NullSafeSet(cmd, value, index);
        }
    
        public override SqlType[] SqlTypes
        {
            get { return new[] {NHibernateUtil.DateTime2.SqlType}; }
        }
    }
    
    [Serializable]
    public class DateTimeKindLocalTypeConvention
        : UserTypeConvention<DateTimeKindLocalType>
    {
    }
    
    [Serializable]
    public class DateTimeKindLocalNullableType : BaseImmutableUserType<DateTime?>
    {
        public override object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            if (owner == null)
                return null;
            return DateTime.SpecifyKind((DateTime)NHibernateUtil.DateTime2.NullSafeGet(rs, names), DateTimeKind.Local);
        }
    
        public override void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            NHibernateUtil.DateTime2.NullSafeSet(cmd, value, index);
        }
    
        public override SqlType[] SqlTypes
        {
            get { return new[] { NHibernateUtil.DateTime2.SqlType }; }
        }
    }
    
    [Serializable]
    public class DateTimeKindLocalNullableTypeConvention
        : UserTypeConvention<DateTimeKindLocalNullableType>
    {
    }
    
    
    [Serializable]
    public abstract class BaseImmutableUserType<T> : IUserType
    {
        public abstract object NullSafeGet(IDataReader rs, string[] names, object owner);
        public abstract void NullSafeSet(IDbCommand cmd, object value, int index);
        public abstract SqlType[] SqlTypes { get; }
    
        public new bool Equals(object x, object y)
        {
            if (ReferenceEquals(x, y))
            {
                return true;
            }
    
            if (x == null || y == null)
            {
                return false;
            }
    
            return x.Equals(y);
        }
    
        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }
    
        public object DeepCopy(object value)
        {
            return value;
        }
    
        public object Replace(object original, object target, object owner)
        {
            return original;
        }
    
        public object Assemble(object cached, object owner)
        {
            return DeepCopy(cached);
        }
    
        public object Disassemble(object value)
        {
            return DeepCopy(value);
        }
    
        public Type ReturnedType
        {
            get { return typeof(T); }
        }
    
        public bool IsMutable
        {
            get { return false; }
        }
    }
    

    如果有问题,请告诉我,我会尽快回答。

    谢谢您的回复。我最终扩展了IUserType,并用新类型创建了UserTypeConvention。我会在回复中发布我的代码。如果这对我有帮助,那就太好了。享受NHibernate;)是的,你的代码确实有帮助。这让我找到了正确的解决方案。谢谢谢谢你的回复。我最终扩展了IUserType,并用新类型创建了UserTypeConvention。我会在回复中发布我的代码。如果这对我有帮助,那就太好了。享受NHibernate;)是的,你的代码确实有帮助。这让我找到了正确的解决方案。谢谢
    BaseImmutableUserType
    来自。是的,谢谢,我忘了它是从哪里来的。感谢您的澄清。
    BaseImmutableUserType
    来自。是的,谢谢,我忘了它是从哪里来的。谢谢你的澄清。