[英]How to map an enum as a foreign key in (Fluent) NHibernate?
How do I map an enum property as an integer foreign key in (Fluent) NHibernate?如何在 (Fluent) NHibernate 中将枚举属性映射为整数外键?
The enum property serves as a type field which is an integer in the database, but it also needs to be a foreign key to a table which contains all the allowable values of that enum (reporting purposes).枚举属性作为一个类型字段,它是数据库中的一个整数,但它也需要是一个表的外键,该表包含该枚举的所有允许值(报告目的)。
Specifically, I need to have a Communication
entity with a Type
field of type enum CommunicationType
mapped as an integer foreign key to the CommunicationType
table.具体来说,我需要有一个Communication
实体,其类型为枚举CommunicationType
的Type
字段映射为CommunicationType
表的整数外键。 Code below.下面的代码。
NOTE : Answers for NHibernate (without Fluent) are accepted also.注意:NHibernate(没有 Fluent)的答案也被接受。
public enum CommunicationType {
General = 1,
ServicesContactEnquiry = 2,
ChangePassword = 3,
OrderDetails = 4,
}
// This is basically the Enum represented in the database for reporting purposes
public class CommunicationTypeRecord {
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
public class Communication {
public virtual CommunicationType Type { get; set; }
// rest of fields ommitted
}
public class CommunicationMap : ClassMap<Communication> {
public CommunicationMap() {
Map(x => x.Type).CustomType<CommunicationType>.Not.Nullable(); // Needs to be FK -> [CommunicationType].[ID]
// rest of fields ommitted
}
}
public class CommunicationTypeRecordMap : ClassMap<CommunicationTypeRecord> {
public CommunicationTypeRecordMap () {
Table("CommunicationType");
Id(x => x.ID).Column("ID").GeneratedBy.Assigned();
Map(x => x.Name).Column("Name").Not.Nullable().CustomType("AnsiString");
Map(x => x.Description).Column("Description").Nullable();
}
}
I tried the following which works for generating the DB correctly, but it doesn't work with hydrating/dehydrating data.我尝试了以下可以正确生成数据库的方法,但它不适用于水合/脱水数据。
References<CommunicationTypeRecord>(x => x.CommunicationType).ForeignKey().Not.Nullable();
Exception:例外:
[ArgumentException: There is a problem with your mappings. You are probably trying to map a System.ValueType to a <class> which NHibernate does not allow or you are incorrectly using the IDictionary that is mapped to a <set>.
A ValueType (CommunicationType) can not be used with IdentityKey. The thread at google has a good description about what happens with boxing and unboxing ValueTypes and why they can not be used as an IdentityKey: http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=bds2rm%24ruc%241%40charly.heeg.de&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26q%3DSystem.Runtime.CompilerServices.RuntimeHelpers.GetHashCode%26sa%3DN%26tab%3Dwg (Parameter 'key')]
Data:
StackTrace:
at NHibernate.Util.IdentityMap.VerifyValidKey(Object obj)
at NHibernate.Util.IdentityMap.set_Item(Object key, Object value)
at NHibernate.Engine.StatefulPersistenceContext.AddChildParent(Object child, Object parent)
at NHibernate.Engine.Cascade.CascadeToOne(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled)
at NHibernate.Engine.Cascade.CascadeAssociation(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled)
at NHibernate.Engine.Cascade.CascadeProperty(Object parent, Object child, IType type, CascadeStyle style, String propertyName, Object anything, Boolean isCascadeDeleteEnabled)
at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything)
at NHibernate.Event.Default.AbstractSaveEventListener.CascadeBeforeSave(IEventSource source, IEntityPersister persister, Object entity, Object anything)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj)
this should work.这应该工作。 can't test it right now.现在无法测试。
public class CommunicationTypeRecord {
public virtual CommunicationType ID { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
public class Communication {
public virtual CommunicationTypeRecord Type { get; set; }
// rest of fields ommitted
}
public class CommunicationMap : ClassMap<Communication> {
public CommunicationMap() {
CompositeId().KeyReference(x => x.Type);
// rest of fields ommitted
}
}
public class CommunicationTypeRecordMap : ClassMap<CommunicationTypeRecord> {
public CommunicationTypeRecordMap () {
Table("CommunicationType");
Id(x => x.ID).Column("ID").CustomType<CommunicationType>().GeneratedBy.Assigned();
Map(x => x.Name).Column("Name").Not.Nullable().CustomType("AnsiString");
Map(x => x.Description).Column("Description").Nullable();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.