Hello,
I implemented an IUserType like there:
http://markmail.org/message/wae5qe5b2kti4qqd#query:+page:1+mid:3jkwktw6226357qs+state:results
Now, everytime I load an entity with this usertype an update is issued (no
actual changes to the entity happen), so I suppose the field is always
considered dirty.
Anyone could give me a pointer on what to do?
Thanks!
Verbose Info following:
public abstract class XmlClassType<T> : IUserType where T : ICloneable
// from what i know nh does not want a generic type there, so it's abstract
{
#region IUserType Members
public new virtual bool Equals(object x, object y)
{
return x == null ? y == null || y.Equals(x) : x.Equals(y);
}
public object NullSafeGet(IDataReader rs, string[] names, object
owner)
{
if (names.Length != 1) throw new
InvalidOperationException("names array has more than one element. can't
handle this!");
var document = new XmlDocument();
var val = rs[names[0]] as string;
if (val != null)
{
document.LoadXml(val);
return Load(document);
}
return null;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var parameter = (DbParameter)cmd.Parameters[index];
if (value == null)
{
parameter.Value = DBNull.Value;
return;
}
parameter.Value = Save((T)value).OuterXml;
}
public object DeepCopy(object value)
{
if (value == null) return null;
var other = (T)value;
return other.Clone();
}
public SqlType[] SqlTypes
{
get { return new SqlType[] { new SqlXmlType() }; }
}
public Type ReturnedType
{
get { return typeof(XmlDocument); }
}
public bool IsMutable
{
get { return true; }
}
public object Assemble(object cached, object owner)
{
return cached;
}
public object Disassemble(object value)
{
return value;
}
public int GetHashCode(object x)
{
return x == null
? typeof(string).GetHashCode() + 123
: x.GetHashCode();
}
public object Replace(object original, object target, object owner)
{
return original;
}
#endregion
protected virtual XmlDocument Save(T data)
{
return SaveValue(data);
}
protected virtual XmlDocument SaveValue(object data)
{
using (var stream = new MemoryStream())
{
var type = data.GetType();
using (XmlWriter writer = new XmlTextWriter(stream,
Encoding.Unicode))
{
var serializer = new XmlSerializer(type);
serializer.Serialize(writer, data);
stream.Seek(0, SeekOrigin.Begin);
var doc = new XmlDocument();
doc.Load(stream);
var typeAttribute = doc.CreateAttribute("type");
typeAttribute.Value = type.AssemblyQualifiedName;
if (doc.DocumentElement == null)
throw new InvalidOperationException("No document
element.");
doc.DocumentElement.Attributes.Append(typeAttribute);
return doc;
}
}
}
protected virtual T Load(XmlDocument value)
{
return (T)LoadValue(value.DocumentElement);
}
protected virtual object LoadValue(XmlNode value)
{
if (value != null)
{
var typeName = value.Attributes["type"].Value;
var type = Type.GetType(typeName);
if (type == null) throw new Exception(string.Format("No
implementing type could be found for the type: {0}", typeName));
using (var stream = new MemoryStream())
{
var document = new XmlDocument();
document.AppendChild(document.ImportNode(value, true));
var serializer = new XmlSerializer(type);
document.Save(stream);
stream.Seek(0, SeekOrigin.Begin);
return serializer.Deserialize(stream);
}
}
return null;
}
}
and concretely as
public class ArrayOfStringsType: XmlClassType<string[]>{}
mapped like this:
<property access="field.camelcase" name="Classifications"
type="xxx.ArrayOfStringsType, xxx.Data, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null">
<column name="Classifications" sql-type="nvarchar(MAX)" />
</property>
and implemented like that:
public virtual string[] Classifications
{
get { return classifications ?? new string[0]; }
}
--
Jan
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.