在nhibernate中将结构映射为Id

时间:2013-04-20 17:40:06

标签: nhibernate struct mapping

我有以下结构和类:

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

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

对于这种情况,我建议使用而不是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。

答案 1 :(得分: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>
相关问题