1

次の構造体とクラスがあります。

public struct DepartmentId{
    public int Value {get; set;}
}

public class Department{
    public virtual DepartmentId Id{get;set;}

    public virtual string Name {get; set;}
}

Department のマッピング ファイルを次のように作成しました。

public class DepartmentMapping : ClassMapping<Department>{
    public DepartmentMapping{
        Table("Department");

        Id(dept => dept.Id, mapper => {
            mapper.Column("Id");
            mapper.Type(new DepartmentIdType());
        });

        Property(dept => dept.Name, mapper => mapper.Column("Name"));
    }
}

DepartmentIdType は IIdentifierType を実装します。

class DepartmentIdType : PrimitiveType, IIdentifierType
{
    public DepartmentIdType() : base(SqlTypeFactory.Int32)
    {
    }

    public override object DeepCopy(object val, EntityMode entityMode, ISessionFactoryImplementor factory)
    {
        return val;
    }

    public override object Replace(object original, object current, ISessionImplementor session, object owner, IDictionary copiedAlready)
    {
        return original;
    }

    public override Type ReturnedClass
    {
        get { return typeof(DepartmentId); }
    }

    public object StringToObject(string xml)
    {
        return new DepartmentId {Value = int.Parse(xml)};
    }

    public override string Name
    {
        get { return typeof(DepartmentId).Name; }
    }



    public override void Set(IDbCommand cmd, object value, int index)
    {
        var id = (DepartmentId) value;
        ((IDataParameter) cmd.Parameters[index]).Value = id.Value;
    }

    public override object Get(IDataReader rs, int index)
    {
        int value = rs.GetInt32(index);

        return new DepartmentId {Value = value};
    }

    public override object Get(IDataReader rs, string name)
    {
        return Get(rs, rs.GetOrdinal(name));
    }

    public override string ToString(object val)
    {
        if (val == null) return "";
        return val.ToString();

    }

    public override object FromStringValue(string xml)
    {
        return new DepartmentId {Value = Int32.Parse(xml)};
    }



    public override object DefaultValue
    {
        get { return new DepartmentId {Value = 0}; }
    }

    public override string ObjectToSQLString(object value, NHibernate.Dialect.Dialect dialect)
    {
        return value.ToString();
    }

    public override Type PrimitiveClass
    {
        get { return typeof(DepartmentId); }
    }
}

ただし、HbmMapping の作成時に、次のエラーが発生します。

Could not compile the mapping document: mapping_by_code

NHibernate.MappingException: Could not compile the mapping document: 
mapping_by_code ---> NHibernate.MappingException: 
Could not determine type for: Demo.Models.DepartmentId,     Demo.Models, 
for columns: NHibernate.Mapping.Column(Id)
at NHibernate.Mapping.SimpleValue.get_Type()
at NHibernate.Cfg.XmlHbmBinding.ClassIdBinder.CreateIdentifierProperty(HbmId idSchema, PersistentClass rootClass, SimpleValue id)
at NHibernate.Cfg.XmlHbmBinding.ClassIdBinder.BindId(HbmId idSchema, PersistentClass rootClass, Table table)
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(HbmClass classSchema, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(HbmClass rootClass, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddEntitiesMappings(HbmMapping mappingSchema, IDictionary`2 inheritedMetas)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(HbmMapping mappingSchema)
at NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping mappingDocument, String documentFileName)

この問題を修正するにはどうすればよいですか (DepartmentId を構造体からクラスに変更せずに)。

よろしくお願いします。

4

2 に答える 2

0

参考までにここに載せておきます。XML マッピングでは、複合 ID としてマッピングすることでこれを行いました。

<class name"Department" ... >
    <composite-id name="Id" access="property"
                  class="DepartmentId">
        <key-property name="Value"
                      column="Id"
                      access="property"
                      type="System.Int32"/>
    </composite-id>
    ... other stuff
</class>
于 2016-05-13T18:13:35.027 に答える
0

この場合、struct の代わりにclassを使用し、Id メソッドの代わりにComponentAsIdを使用することをお勧めします。ID ジェネレーターを使用しない場合は、ハッキングのない簡単な方法です。

public class DepartmentMapping : ClassMapping<Department> {
public DepartmentMapping{
    Table("Department");
    ComponentAsId(dept => dept.Id);
    Property(dept => dept.Name, mapper => mapper.Column("Name"));
}}

public class DepartmentIdMapping : ComponentMapping<DepartmentId> {
public DepartmentIdMapping{
    Property(x=> x.Value, mapper => mapper.Column("Id"));
}}

この強力な型付き ID と ID 生成を調査するときにあなたのアプローチを試しましたが、最終的にカスタム Hi/Lo ジェネレーターを実装し、NHibernate 割り当て ID を使用することにしました。

于 2013-07-10T11:04:28.317 に答える