我正在通过Oracle10g提供程序使用Oracle.DataAccess从外部组织读取数据。其中一个表具有由这些字段组成的复合ID。
course:
institutioncode: "X11"
coursecode: "N100"
campuscode: "A"
entryyear: 2011
entrymonth: 10
问题是外部提供商允许校园代码为空,而不是空。这导致nHibernate返回包含空引用而不是课程实体的集合。
其他域对象也将使用这些字段来引用此课程实体,因此这实际上用作键,我不能轻易地重新映射以使用代理键。
从标记3.1.0GA中的来源,可以在Nhibernate.Type.ComponentType.Hydrate(IDataReader rs, string[] names, ISessionImplementor session, object owner)
中找到导致此行为的检查。这总是拒绝key-property可能为null的可能性。这可以改为使可空性成为关键属性和键引用属性的一个选项吗?
如果不这样做,你会如何建议直接用nHibernate读取这些数据?
答案 0 :(得分:2)
属性中的NULL值不受设计支持。
有两种方法可以解决这个问题:
答案 1 :(得分:1)
好的,我的第一条评论在参考文献(ManyToOne)上没有成功。所以这里是我的替代解决方案:使用usertype来解决检查问题。
class CourseMap : ClassMap<Course>
{
public CourseMap()
{
CompositeId()
.KeyProperty(c => c.InstitutionCode)
.KeyProperty(c => c.CourseCode)
.KeyProperty(c => c.CampusCode, key => key.Type(typeof(MyUserType)))
.KeyProperty(c => c.EntryYear)
.KeyProperty(c => c.EntryMonth);
}
}
class MyUserType : IUserType
{
public object Assemble(object cached, object owner)
{
return DeepCopy(cached);
}
public object DeepCopy(object value)
{
return value;
}
public object Disassemble(object value)
{
return DeepCopy(value);
}
public new bool Equals(object x, object y)
{
return object.Equals(x, y);
}
public int GetHashCode(object x)
{
return (x == null) ? 0 : x.GetHashCode();
}
public bool IsMutable
{
get { return false; }
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var value = NHibernateUtil.String.NullSafeGet(rs, names[0]);
return (value == null) ? string.Empty : value;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
string d = string.IsNullOrEmpty((string)value) ? null : (string)value;
NHibernateUtil.String.NullSafeSet(cmd, d, index);
}
public object Replace(object original, object target, object owner)
{
return DeepCopy(original);
}
public Type ReturnedType
{
get { return typeof(string); }
}
public SqlType[] SqlTypes
{
get { return new[] { SqlTypeFactory.GetString(100) }; }
}
}
class SomeEntityMap : ClassMap<SomeEntity>
{
public EntityMap()
{
Id(e => e.Id).GeneratedBy.Assigned();
References(e => e.Course)
.Columns("InstitutionCode", "CourseCode", "CampusCode", "EntryYear", "EntryMonth")
.Fetch.Join(); // important because we can't rely on values, NULL is invalid value
}
}