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.

Reply via email to