テーブルの主キー値に VARCHAR(8) として格納されたゼロで埋められた数値を使用する従来のデータベースがあります。(例:「00032982」)
これらを文字列ではなく、エンティティ オブジェクトの Int32 プロパティにマップしたいと考えています。
私の最初の試みは、IUserType を実装するクラスを作成することでした。しかし、私はプロパティではなくIDをマッピングしていて、コードによるマッピングはコンパイルされません:(多分私はその部分を正しくやっていませんか?)
Argument 1: cannot convert from 'TestQWebApi.Infrastructure.StringIntUserType' to 'NHibernate.Type.IIdentifierType'
IIdentifierType を調べたところ、40 を超えるメンバーが含まれています。私はあちこちを見回しましたが、NHibernate.Type.ImmutableType をサブクラス化するカスタム型を作成することが解決策になるように思えました。(……もしかして、これが最初のミス?)
そこで、 Set() メソッドでゼロを埋め込む ImmutableType に基づいて新しいクラスを作成しました。
public class LegacyIntKeyType : ImmutableType, ILiteralType, IDiscriminatorType
{
public LegacyIntKeyType() : base(SqlTypeFactory.GetString(8))
{
}
public override string Name
{
get { return "LegacyIntKeyType"; }
}
public override object Get(IDataReader rs, int index)
{
try
{
return Convert.ToInt32(rs[index]);
}
catch (Exception ex)
{
throw new FormatException(string.Format("Input string '{0}' was not in the correct format.", rs[index]), ex);
}
}
public override object Get(IDataReader rs, string name)
{
try
{
return Convert.ToInt32(rs[name]);
}
catch (Exception ex)
{
throw new FormatException(string.Format("Input string '{0}' was not in the correct format.", rs[name]), ex);
}
}
public override System.Type ReturnedClass
{
get { return typeof(Int32); }
}
public override void Set(IDbCommand rs, object value, int index)
{
((IDataParameter)rs.Parameters[index]).Value = string.Format("{0:d8}", value.ToString());
}
public object StringToObject(string xml)
{
return FromStringValue(xml);
}
public override object FromStringValue(string xml)
{
return Int32.Parse(xml);
}
public string ObjectToSQLString(object value, Dialect dialect)
{
return value.ToString();
}
public override string ToString(object value)
{
return value.ToString();
}
}
基本エンティティ クラスでは、Int32 として定義しています。
public abstract class Entity
{
public virtual Int32 Id { get; protected set; }
}
それから私はそれをマッピングしようとしました:
public class ProcedureMap : ClassMapping<Procedure>
{
public ProcedureMap()
{
Table("procfile");
Id(x => x.Id, m =>
{
m.Column("key_proced");
m.Type(new LegacyIntKeyType());
});
Property(x => x.Name, m => m.Column("procname"));
}
}
次に、この例外が発生します...おそらく何か他のことを示していると感じています。スタック トレースは次のとおりです。
[MappingException: Could not determine type for: TestQWebApi.Models.LegacyIntKeyType, TestQWebApi, for columns: NHibernate.Mapping.Column(key_proced)]
NHibernate.Mapping.SimpleValue.get_Type() +317
NHibernate.Cfg.XmlHbmBinding.ClassIdBinder.CreateIdentifierProperty(HbmId idSchema, PersistentClass rootClass, SimpleValue id) +301
NHibernate.Cfg.XmlHbmBinding.ClassIdBinder.BindId(HbmId idSchema, PersistentClass rootClass, Table table) +396
NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(HbmClass classSchema, IDictionary`2 inheritedMetas) +987
NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(HbmClass rootClass, IDictionary`2 inheritedMetas) +104
NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddEntitiesMappings(HbmMapping mappingSchema, IDictionary`2 inheritedMetas) +165
NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(HbmMapping mappingSchema) +117
NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping mappingDocument, String documentFileName) +244
前もって感謝します!