Hi
I created a class that implements the IUserType called LayoutType to write the information in a class called Layout to a single column as a string. The following code works.
Attempt a = new Attempt();
a.Timestart = DateTime.Now;
a.Timefinish = DateTime.Now + new TimeSpan(0, 45, 0);
a.Quiz = session.Load<Quiz>(42);
a.Sumgrade = 0;
QuestionIDCollection pks = new QuestionIDCollection();
pks.Add(174);
pks.Add(175);
pks.Add(98);
a.Layout.Add(pks);
a.User = session.Load<User>(4002);
session.Save(a);
but the next code does not work. the session fails to see the Layout property as dirty for some reason and will not call session.update on that property.
session.Load<Attempt>(10);
Response.Write("a.Layout.Count : " + a.Layout.Count + "<br />");
QuestionIDCollection pks = new QuestionIDCollection();
pks.Add(11);
pks.Add(22);
pks.Add(33);
a.Layout.Add(pks);
session.Update(a);
Can you please help me fix this problem with my Layout property not being synchronized with the database whenever it is updated.
1.2.0GA
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<!--Build: with lujan99@usa.net Nhibernate template-->
<class name="Econcordia.Quiz.Attempt,Econcordia.Quiz" table="Quiz.Attempt" lazy="true">
<cache usage="nonstrict-read-write" region="foo" />
<id name="Id" column="id" type="long">
<generator class="native" />
</id>
<property name="Timestart" column="timestart" type="DateTime" not-null="true" />
<property name="Timefinish" column="timefinish" type="DateTime" not-null="true" />
<property name="Sumgrade" column="sumgrade" type="double" not-null="true" />
<many-to-one name="User" column="user_id" cascade="save-update" not-null="true" />
<many-to-one name="Quiz" column="quiz_id" cascade="save-update" not-null="true" />
<!--<property name="Layout" column="layout" type="string" not-null="true" />-->
<property name="Layout" column="layout" type="Econcordia.Quiz.Types.LayoutType, Econcordia.Quiz" not-null="true" />
<bag name="QuestionStates" inverse="true" lazy="true" cascade="delete">
<cache usage="nonstrict-read-write" region="foo" />
<key column="attempt_id" />
<one-to-many class="Econcordia.Quiz.QuestionState,Econcordia.Quiz" />
</bag>
</class>
</hibernate-mapping>
Here is the class
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Econcordia.Quiz
{
[Serializable]
public class Layout : List<QuestionIDCollection>
{
public int something = 3;
public Layout()
{
}
}
[Serializable]
public class QuestionIDCollection : List<long>
{
public QuestionIDCollection()
{
}
}
}
here is the LayoutType Class which doesn't call the NullSafeSet method when the Layout property is updated.
using System;
using System.Collections.Generic;
using System.Text;
using NHibernate.UserTypes;
using System.Data;
using NHibernate;
using NHibernate.SqlTypes;
using System.IO;
using System.Xml.Serialization;
namespace Econcordia.Quiz.Types
{
public class LayoutType : IUserType
{
public new bool Equals(object x, object y)
{
return object.Equals(x, y);
}
public int GetHashCode(Object x)
{
return x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
string data = NHibernateUtil.String.NullSafeGet(rs, names).ToString();
return this.Deserialize(data);
}
public void NullSafeSet(IDbCommand statement, object value, int index)
{
if (value == null)
{
((IDbDataParameter)statement.Parameters[index]).Value = "";
}
else
{
Layout layout = value as Layout;
NHibernateUtil.String.Set(statement, this.Serialize(layout), index);
}
}
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 SqlType[] SqlTypes
{
get { return new SqlType[] { NHibernateUtil.String.SqlType }; }
}
public System.Type ReturnedType
{
//get { return typeof(String); }
get { return typeof(Layout); }
}
public bool IsMutable
{
//get { return NHibernateUtil.String.IsMutable; }
get { return false; }
}
private string Serialize(Layout layout)
{
UTF8Encoding encoding = new UTF8Encoding();
MemoryStream stream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(Layout));
xs.Serialize(stream, layout);
return encoding.GetString(stream.ToArray());
}
private Layout Deserialize(string data)
{
UTF8Encoding encoding = new UTF8Encoding();
XmlSerializer xs = new XmlSerializer(typeof(Layout));
byte[] array = encoding.GetBytes(data);
MemoryStream stream = new MemoryStream(array);
return xs.Deserialize(stream) as Layout;
}
}
}
I would appreciate any help that could fix the problem I am having.
Thanking you in advance
Francis