我将为一个字符串属性实现一个ICompositeUserType,它被分成4列2000个字符(在传统的oracle数据库中,以避免CLOB / LONG字段)。 实现界面似乎是个好主意,但我无法理解SetPropertyValue方法。它不接受类型或字符串值。我需要它是可变的,所以我需要实现这个方法。
我可以使用非持久性属性来封装拆分并连接到x persitent属性,但我想要更透明的东西。
我发现了类似的问题,但没有像我预期的那样回应。
- 更新 -
我上传了一些代码来为问题添加上下文:
数据库:
...
Value VARCHAR2(2000 BYTE)
Value2 VARCHAR2(2000 BYTE)
Value3 VARCHAR2(2000 BYTE)
Value4 VARCHAR2(2000 BYTE)
Value5 VARCHAR2(2000 BYTE)
...
HBM:
<property name="Value" type="MyAssembly.NHibernateUtils.Types.MultiColumnJoinedUserType, MyAssembly">
<column name="DFM_Value"/>
<column name="DFM_Value2"/>
<column name="DFM_Value3"/>
<column name="DFM_Value4"/>
<column name="DFM_Value5"/>
</property>
CLASS:
public virtual string Value { get; set; }
MultiColumnJoinedUserType:
/// <summary>
/// Set the value of a property
/// </summary>
/// <param name="component">an instance of class mapped by this "type"</param>
/// <param name="property"></param>
/// <param name="value">the value to set</param>
public void SetPropertyValue(object component, int property, object value) { ... }
在我的班级中,方法的组件字段是一个字符串,因此在不更改引用的情况下无法更改其值,因为字符串作为值而不是作为我需要的引用传递。
答案 0 :(得分:1)
ICompositeUserType
通常用于.Net中有多个属性(例如&#34;组件&#34;)。这里有Money
课程的示例:http://geekswithblogs.net/opiesblog/archive/2006/08/05/87218.aspx
由于.Net中只有一个简单值,因此您应该实现IUserType
,这样您仍然可以在数据库中使用多个列。
答案 1 :(得分:0)
我在这个问题上花了几个小时尝试了各种解决方案:
两者都在Oracle中工作,但在SQL中(我需要兼容性),空值被设置为默认的null。
log4net中的NHibernate跟踪:
INSERT INTO VALUETABLE (HDF_Value1, HDF_Value2, HDF_Value3, HDF_Value4, HDF_Value5) VALUES (@p1, @p2, @p3, @p4, @p5); select SCOPE_IDENTITY(); @p1 = NULL [Type: String (4000)], @p2 = NULL [Type: String (4000)], @p3 = NULL [Type: String (4000)], @p4 = NULL [Type: String (4000)], @p5 = NULL [Type: String (4000)]
但是在SQLProfiler中:
exec sp_executesql N'INSERT INTO VALUETABLE (HDF_Value1, HDF_Value2, HDF_Value3, HDF_Value4, HDF_Value5) VALUES (@p1, @p2, @p3, @p4, @p5); select SCOPE_IDENTITY()',N'@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 nvarchar(4000),@p4 nvarchar(4000),@p5 nvarchar(4000)',@p1=default,@p2=default,@p3=default,@p4=default,@p5=default
我在nullsafeset上尝试过各种代码(使用DBNull,string.NullSafeSet,...),但对我来说没有任何作用。我不能浪费更多时间,最后我实施了最简单的解决方案,5&#34;隐藏&#34;映射对象上的属性和&#34;虚拟&#34;分割和连接值的属性,它不是非常透明但它按预期工作:
public virtual string _Value1 { get; set; }
public virtual string _Value2 { get; set; }
public virtual string _Value3 { get; set; }
public virtual string _Value4 { get; set; }
public virtual string _Value5 { get; set; }
public virtual string Value
{
get
{
// JOIN VALUES FROM 5 _Value properties
}
set
{
// SPLIT VALUE INTO 5 _Value properties
}
}
这一刻对我来说足够了。
答案 2 :(得分:0)
字符串不可变。您可以放心地忽略SetPropertyValue
。我在我的不可变用户类型中实现了GetPropertyValue
,我认为它被调用。
public bool IsMutable
{
get { return false; }
}
public void SetPropertyValue(object component, int property, object value)
{
throw new NotSupportedException("Something goes wrong here");
}
public object GetPropertyValue(object component, int property)
{
var stringComponent = (string)component;
maxLengthToRead = Math.Min(2000, stringComponent.Length - property * 2000);
if (maxLengthToRead <= 0) return string.Empty;
return stringComponent.Substring(property * 2000, maxLengthToRead);
}