1

我有以下结构和类:

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

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

    public virtual string Name {get; set;}
}

我为部门创建了一个映射文件,如下所示:

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 从 struct 更改为 class)?

在此先感谢您的帮助。

4

2 回答 2

0

对于这种情况,我建议使用class而不是 struct 和ComponentAsId而不是 Id 方法。如果您不使用 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 回答
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 回答