我正在尝试将Guid(不是Id属性)映射到Oracle CLOB列。
在MsSQL中,我可以将Guid映射到UniqueIdentifier
列,如下所示:
Map(x => x.Guid).Column("my_guid").CustomType<GuidType>();
我在我的业务实体的构造函数中生成Guid:
public MyEntity()
{
this.Guid = Guid.NewGuid();
}
但是,当尝试将Guid映射到Oracle中的CLOB时,使用适用于MsSQL的相同映射,它总是插入一个NULL值。
如果可以像解决Guid Id字段的映射问题那样解决这个问题会很方便:
Id(x => x.Id).Column("my_guid").GeneratedBy.GuidComb();
答案 0 :(得分:1)
我真的找不到一个好方法,但是,我已经提出了一个可行的解决方案。
如果我们在Oracle中使用数据类型NOT NULL VARCHAR2(32) DEFAULT SYS_GUID()
创建一个列,这将在插入记录时处理Guid的生成。
但是,Oracle会生成没有连字符的Guid,因此我们得到的内容看起来像EF8FDA432CB340ADE0434C687B89F91C
。
不幸的是,由于这个原因,我不得不创建自己的IUserType
实现来处理将带有连字符的Guid转换为存储为VARCHAR2(32)
而没有连字符的Oracle的Guid。实施如下:
[Serializable]
public class OracleGuidType : IUserType
{
SqlType[] sqlTypes;
public OracleGuidType()
{
// We use DbType.String here because we are storing as a varchar
sqlTypes = new[] { SqlTypeFactory.GetSqlType(DbType.String, 0, 0) };
}
public SqlType[] SqlTypes
{
get { return sqlTypes; }
}
public Type ReturnedType
{
get { return typeof(Guid); }
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
if (rs[names[0]] == DBNull.Value)
{
return Guid.Empty;
}
return new Guid(rs[names[0]].ToString());
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var param = (IDataParameter)cmd.Parameters[index];
param.DbType = sqlTypes[0].DbType;
var guid = (Guid)value;
if (guid != Guid.Empty)
{
// This line removes hyphens
param.Value = guid.ToString("N").ToUpper();
}
else
{
param.Value = DBNull.Value;
}
}
public bool IsMutable
{
get { return false; }
}
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 cached;
}
public object Disassemble(object value)
{
return value;
}
public new bool Equals(object x, object y)
{
return x != null && x.Equals(y);
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
}
我的NHibernate映射定义为:
Map(x => x.Guid).Column("my_guid").Generated.Insert().CustomType<OracleGuidType>();