我有一个包含枚举集合的类,如下所示。
public enum TransactionType
{
...
}
public class PaymentMethod
{
...
public virtual IList<TransactionType> SupportedTransactionTypes { get; set; }
}
对TransactionType枚举的其他引用正常工作,但是对于这个集合,我得到一个异常:“NHibernate.MappingException:Association引用unmapped class:mynamespace.TransactionType”。
环顾四周似乎我需要指定元素映射的类型,即一对多,元素或复合元素。
我为PaymentMethod类设置了以下覆盖映射:
mapping.HasMany(x => x.TransactionTypes)
.Element("TransactionTypeId"), x => x.Type<TransactionType>());
但这导致以下异常...
验证失败:System.NullReferenceException:未将对象引用设置为对象的实例。 在E:\ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Conventions \ Inspections \ OneToManyInspector.cs:40行的FluentNHibernate.Conventions.Inspections.OneToManyInspector.get_Class()中 在FluentNHibernate.Conventions.ProxyConvention.Apply(ICollectionInstance实例)中的e:\ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Conventions \ ProxyConvention.cs:第79行 在FluentNHibernate.Visitors.ConventionVisitor.Apply [TInspector,TInstance](IEnumerable convention,TInstance实例)中的e:\ horn.horn \ orm \ fluentnhibernate \ Working \ src \ FluentNHibernate \ Visitors \ ConventionVisitor.cs:第269行 在......
我在映射上尝试了很多不同的变体,包括TableName,KeyColumn和我能想到的任何其他东西,但是我无法使这个映射起作用。
任何帮助表示赞赏...
答案 0 :(得分:3)
也许这是FluentNHibernate最近的修复,但这适用于FluentNH v1.2.0.712。我相信NHibernate与普通* .hbm.xml映射多年来一直支持这种映射。
这是对我有用的自动覆盖:
mapping.HasMany(x => x.SupportedTransactionTypes)
.Element("TransactionTypeId");
...导致这个XML ......
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="so.Q2676867.PaymentMethod, so, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`PaymentMethod`">
<id access="backfield" name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Id" />
<generator class="identity" />
</id>
<bag name="SupportedTransactionTypes">
<key>
<column name="PaymentMethod_id" />
</key>
<element type="so.Q2676867.TransactionType, so, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<column name="TransactionTypeId" />
</element>
</bag>
</class>
</hibernate-mapping>
......以及这些表:
create table [PaymentMethod] (
Id INT IDENTITY NOT NULL,
primary key (Id)
)
create table SupportedTransactionTypes (
PaymentMethod_id INT not null,
TransactionTypeId INT null
)
alter table SupportedTransactionTypes
add constraint FK738E3751B597A1C
foreign key (PaymentMethod_id)
references [PaymentMethod]
......这正是我所期待的。 Yay NHibernate!
答案 1 :(得分:1)
您可以将数据库中的集合作为管道分隔的字符串...
保留 protected string _enumCollection = "";
public virtual ISet<MyEnum> EnumCollection
{
get
{
var set = new HashedSet<MyEnum>();
if (string.IsNullOrEmpty(_enumString))
return set;
_enumCollection.Split(new[] {"|"}, StringSplitOptions.None).ToList()
.ForEach(
x => set.Add((MyEnum)(Int32.Parse(x)))
);
return new HashedSet<MyEnum>(set);
}
set { _enumCollection = string.Join("|", value.Select(x => ((int)x).ToString()).ToArray()); }
}
然后映射到字符串后备字段:
Map(x => x.EnumCollection).CustomType(typeof(string)).Access.CamelCaseField(Prefix.Underscore);
您需要使用辅助方法来添加/删除枚举,而不是使用集合本身的方法来更新支持字段。
public virtual void AddEnum(MyEnum enum)
{
if (!EnumCollection.Contains(enum))
{
var set = EnumCollection; //you need to get the collection
set.Add(enum); //add enum to it
EnumCollection= set; //then set the set again
}
}
public virtual void RemoveEnum(MyEnum enum)
{
if (EnumCollection.Contains(enum))
{
var set = EnumCollection; //get collection
set.Remove(enum); //add enum
EnumCollection= set; //re-set collection
}
}
希望这有帮助。
答案 2 :(得分:0)
我不认为你可以映射一组枚举。你肯定不会在一年左右之前