NHibernate,试图将对象作为字符串存储在DB中



我试图实现的是以某种形式序列化一个对象,并将其存储在数据库中,然后重新创建它。

这是结构:我正在使用https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/using-conversion-operators用于转换

public class Order : AggregateRoot
{
private string _cityList;
public virtual CityList CityList { get => (CityList)_cityList; }
}
public class CityList : ValueObject
{
private string _cities { get; }
public CityList(string cities)
{
_cities = cities;
}
public static explicit operator CityList(string cityList)
{
return new CityList(cityList);
}
public static implicit operator string(CityList cityList)
{
return (string)cityList;
}
}

这是配置

mapping
.Map(Reveal.Member<Order>("CityList"))
.CustomType("string")
.Column("CityList");

这就是我得到的

处理请求时发生未处理的异常。InvalidCastException:无法将CityList类型的对象强制转换为System.String 类型

NHibernate.Type.AbstractStringType.Set(DbCommand cmd,object value,int index,ISessionImplementor会话(PropertyValueException:对CityList的属性值进行脱水时出错Command.Stack.Adapters.Base.UnitOfWork.IUnitOfWork.CommitAsync(CancellationToken取消代币(

我为什么要得到这个?以及如何解决?

需要明确的是,这不是您问题的确切答案,但希望提供另一种方法来实现这一点。我们创建了名为JsonMappable Type的自定义IUserType。这种类型将保存到DB中的数据序列化和反序列化为JSON字符串,您需要覆盖NullSafeGet和Set,然后很容易在映射文件中这样映射它

Property(p => p.UserAvailability, m =>
{
m.Type<JsonMappableType<UserAvailability>>();
});

此链接提供如何实现iusertype

如何正确实现IUserType?

您可以使用IUserType接口。

[Serializable]
public class AsClobStringUserType<T> : IUserType
{
public AsClobStringUserType()
{

}
/// <summary>
/// The type returned by NullSafeGet()
/// </summary>
Type IUserType.ReturnedType => typeof(T);
bool IUserType.IsMutable => false;
SqlType[] IUserType.SqlTypes => new SqlType[] { new StringClobSqlType() };
/// <summary>
/// Used for casching, the object is immutable, just return 
/// </summary>
/// <param name="cached"></param>
/// <param name="owner"></param>
/// <returns></returns>
object IUserType.Assemble(object cached, object owner)
{
return cached;
}
/// <summary>
/// Deep copy the Translation by creating a new instance with the same contents
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
object IUserType.DeepCopy(object value)
{
if (value == null) return null;
if (value.GetType() != typeof(T)) return null;
string jsonString = JsonSerializationService.Instance.Serialize((T)value);
return JsonSerializationService.Instance.Deserialize<T>(jsonString);
}
/// <summary>
/// Used for casching, the object is immutable, just return 
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
object IUserType.Disassemble(object value)
{
return value;
}
/// <summary>
/// Use json string to check the equality
/// </summary>
/// <param name="object1"></param>
/// <param name="object2"></param>
/// <returns></returns>
bool IUserType.Equals(object object1, object object2)
{
if (ReferenceEquals(object1, null) && ReferenceEquals(object2, null)) return true;
if (ReferenceEquals(object1, null) || ReferenceEquals(object2, null)) return false;
return JsonSerializationService.Instance.Serialize((T)object1) == JsonSerializationService.Instance.Serialize((T)object2);
}
/// <summary>
/// 
/// </summary>
/// <param name="object"></param>
/// <returns></returns>
int IUserType.GetHashCode(object @object)
{
if (@object != null && @object.GetType() == typeof(T))
{
return JsonSerializationService.Instance.Serialize((T)@object).GetHashCode();
}
return @object.GetHashCode();
}
#region Serialization
/// <summary>
/// Retrieve an instance of the mapped class from.
/// </summary>
/// <remarks>
/// Should handle possibility of null values.
/// </remarks>
/// <param name="owner">the entity to work with. (serialized object)</param>
object IUserType.NullSafeGet(DbDataReader rs, string[] names, ISessionImplementor session, object owner)
{
/// => Translation should be stored in single column 
if (names.Length != 1) throw new InvalidOperationException("Translation should be stored in single column.");
string value = rs[names[0]] as string;
if (!string.IsNullOrWhiteSpace(value)) return JsonSerializationService.Instance.Deserialize<T>(value);
return null;
}
/// <summary>
/// Write an instance of the mapped class to a prepared statement.
/// </summary>
/// <remarks>
/// Should handle possibility of null values.
/// </remarks>
/// <param name="cmd">the object to be serialized and written to persistence store.</param>
/// <param name="value">the object to be serialized and written to persistence store.</param>
void IUserType.NullSafeSet(DbCommand cmd, object value, int index, ISessionImplementor session)
{
DbParameter parameter = cmd.Parameters[index];
if (value == null)
{
parameter.Value = DBNull.Value;
}
else
{
parameter.Value = JsonSerializationService.Instance.Serialize(value);
}
}
#endregion
/// <summary> 
/// As our object is immutable just return the original
/// </summary>
/// <param name="original"></param>
/// <param name="target"></param>
/// <param name="owner"></param>
/// <returns></returns>
object IUserType.Replace(object original, object target, object owner)
{
return original;
}
}

相关内容

  • 没有找到相关文章

最新更新