gpt4 book ai didi

c# - NHibernate IUserType 未应用于插入

转载 作者:行者123 更新时间:2023-11-29 11:36:30 24 4
gpt4 key购买 nike

我使用 NHibernate 和 Postgresql 作为后端,并且必须创建自定义类型以将 System.DateTime 转换为 Postgresql“时间”类型以及将 System.TimeSpans 转换为“间隔”数据库类型。我创建的 IUserType 正在工作并且正在应用于读取和更新但是当我尝试将对象插入数据库时​​它们从未被应用。我在 IUserTypes 中设置了断点,但是当发生插入时它们永远不会被击中。

我认为问题可能在于该对象只是一个 POCO 对象并且还不是代理,因此当我设置我的属性值时,不会发生将转换应用于用户类型的映射。

如果我进行更新并设置这些属性之一,我可以看到 IUserType 中的断点被触发。

有什么想法吗?

更新正在调用 IUserType 的 Equals 方法,但没有调用我进行必要转换的 NullSafeSet。

编辑添加了代码示例

    public class TimeType : BaseImmutableUserType<TimeSpan>
{
public override object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var val = NHibernateUtil.Time.NullSafeGet(rs, names[0]);
if (val == null)
return null;

var dt = DateTime.Parse(val.ToString());

return new TimeSpan(0, dt.Hour, dt.Minute, dt.Second);
}

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

((IDbDataParameter) cmd.Parameters[index]).Value = obj;
}

public override SqlType[] SqlTypes
{
get
{
return new[] { SqlTypeFactory.Time };
}
}
}

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 BaseImmutableUserType()
{
int i = 0;
}

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; }
}
}

最佳答案

我找到了以下两个选项:

选项 1:不使用您自己的 UserType。而是像这样使用 NHibernate 自己的 TimeAsTimeSpan:

Map(x => x.TimeFrom)
.CustomType("TimeAsTimeSpan");

(示例取自 here )

选项 2:稍微修改您的类:

public class TimeType : BaseImmutableUserType<TimeSpan>
{
// this is taken from the source of NHibernate.Type.TimeAsTimeSpanType
private static readonly DateTime BaseDateValue = new DateTime(1753, 01, 01);

public override object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var val = NHibernateUtil.TimeAsTimeSpan.NullSafeGet(rs, names[0]);
if (val == null)
return null;

var dt = DateTime.Parse(val.ToString());

return new TimeSpan(0, dt.Hour, dt.Minute, dt.Second);
}

public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
//var obj = (TimeSpan)value; // we can't use TimeSpan here but need to use DateTime
// this is taken from the source of NHibernate.Type.TimeAsTimeSpanType
DateTime date = BaseDateValue.AddTicks(((TimeSpan)value).Ticks);
((IDbDataParameter)cmd.Parameters[index]).Value = date;
}

public override SqlType[] SqlTypes
{
get
{
return new[] { NHibernate.SqlTypes.SqlTypeFactory.Time };
}
}
}

关于c# - NHibernate IUserType 未应用于插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6154636/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com