Reputation: 26257
I have a class in NHibernate where I wish to map properties to custom datatypes.
The NHibernate class looks something like this
namespace Example1.Models
{
public class Calendar
{
public virtual int ID { get; set; }
public virtual string Workspace { get; set; }
}
}
With a mapping file
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
<class name="Example1.Models.Calendar, Example1" lazy="true" table="Calendar">
<id name="ID">
<generator class="native" />
</id>
<property name="Workspace" />
</class>
</hibernate-mapping>
The workspace coming in the Workspace property looks like this
http://site/Morning%20meeting?InstanceID=1, Morning meeting
I can use the Uri class to map this as an URL but in some cases I need to also have the title shipped with the string
public class Calendar
{
public virtual int ID { get; set; }
private Uri _workspace;
public virtual Uri Workspace
{
get { return _workspace; }
set
{
if (value != null)
{
var workspace = value.ToString().Split(new[] { ',' });
_workspace = new Uri(workspace[0]);
}
}
}
}
I tried to create a custom class and sed the workspace type to that class, in example
private Workspace _workspace;
public virtual Workspace Workspace
{
get { return _workspace; }
set { _workspace = new Workspace(value.ToString()); }
}
...
public class Workspace
{
public Uri Uri { get; set; }
public string Title { get; set; }
public Workspace(string workspace)
{
if(string.IsNullOrEmpty(workspace))
return;
var workspaceArray = workspace.Split(new[] { ',' });
if (workspaceArray.Length > 0)
Uri = new Uri(workspaceArray[0]);
if (workspaceArray.Length > 1)
Title = workspaceArray[1];
}
}
This will render the error
Could not determine type for:Example1.Models.Workspace, Example1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, for columns: NHibernate.Mapping.Column(Workspace)
What would be the recommended way to implement this kinds of customizations?
Thanks
Upvotes: 1
Views: 1027
Reputation: 26257
Did solve by implementing the IUserType
This code is still a work in progress but it does work
The property in the NHibernate class
private Workspace _workspace;
public virtual Workspace Workspace
{
get { return _workspace; }
set
{
if (value != null)
{
_workspace = value;
}
}
}
The property in the hbm file
<property name="Workspace" type="Example1.Models.WorkspaceType, Example1" />
And the IUserType implementation
public interface IWorkspace
{
Uri Uri { get; set; }
string Title { get; set; }
}
public class Workspace : IWorkspace
{
#region Implementation of IWorkspace
public Uri Uri { get; set; }
public string Title { get; set; }
#endregion
public Workspace(string workspace)
{
if (string.IsNullOrEmpty(workspace))
return;
var workspaceArray = workspace.Split(new[] { ',' });
if (workspaceArray.Length > 0)
Uri = new Uri(workspaceArray[0]);
if (workspaceArray.Length > 1)
Title = workspaceArray[1];
}
}
public class WorkspaceType : IUserType
{
#region Implementation of IUserType
public bool Equals(object x, object y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
return x.GetType() == y.GetType();
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var property0 = NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (property0 == null)
{
return null;
}
Workspace workspace = new Workspace(property0.ToString());
return workspace;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (value == null)
{
((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
}
else
{
var state = (IWorkspace)value;
((IDataParameter)cmd.Parameters[index]).Value = state.GetType().Name;
}
}
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[] { NHibernateUtil.String.SqlType }; } }
public Type ReturnedType { get { return typeof(Workspace); } }
public bool IsMutable { get { return false; } }
#endregion
}
Upvotes: 2