我真的很难让我的第一个NHibernate项目离开地面,我认为我的问题主要围绕着Enums。我目前遇到以下异常:
System.InvalidOperationException: Tried to add property 'Name' when already added.
我已经下载了Fluent NHibernate源代码并在发生异常的地方设置了一个断点,并且能够将其固定为与EnumStringType有关。
我定义了以下类:
public class CurrencyStringType : EnumStringType<Currency>
{
}
以下列举:
public enum Currency
{
GBP = 826,
USD = 840,
EUR = 978
}
本部分模型使用的是:
public class ExchangeRate
{
[Key, Column(Order = 1)]
public virtual int JobId { get; set; }
[Key, Column(Order = 2), MaxLength(3)]
public virtual Currency Source { get; set; }
[Key, Column(Order = 3), MaxLength(3)]
public virtual Currency Target { get; set; }
public virtual decimal Rate { get; set; }
public virtual Job Job { get; set; }
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as ExchangeRate;
if (t == null)
return false;
if (this.Job == t.Job & this.Source == t.Source && this.Target == t.Target)
return true;
return false;
}
public override int GetHashCode()
{
return (this.JobId + "|" + this.Source + "|" + this.Target).GetHashCode();
}
}
映射覆盖如下:
public void Override(AutoMapping<ExchangeRate> mapping)
{
// Define the composite key
mapping.CompositeId()
.KeyProperty(e => e.JobId, "JobId")
.KeyReference(e => e.Source)
.KeyReference(e => e.Target);
}
我现在已经苦苦挣扎了2天以上,试图让我的Enums与Fluent NHibernate一起工作 - 由于某些原因,这似乎非常复杂。
更新:我创建了一个新的映射替换,如下所示......
public class CurrencyStringTypeMap : IAutoMappingOverride<CurrencyStringType>
{
public void Override(AutoMapping<CurrencyStringType> mapping)
{
mapping.IgnoreProperty(m => m.Name);
}
}
正如预期的那样,它克服了最初的异常,但它只是被替换为同样的但是对于另一个也属于EnumStringtype的属性,这让我觉得可能在某处有一个bug?添加上述覆盖后的新异常如下:
Tried to add property 'PrimitiveClass' when already added
我最终通过以下手动映射类解决了这个问题:
/// <summary>
/// Defines the mapping for ExchangeRates
/// </summary>
public class ExchangeRateMap : ClassMap<ExchangeRate>
{
/// <summary>
/// Initializes a new instance of the <see cref="ExchangeRateMap"/> class.
/// </summary>
public ExchangeRateMap()
{
Table("ExchangeRates");
CompositeId()
.KeyProperty(e => e.JobId, "JobId")
.KeyProperty(e => e.Source, "Source")
.KeyProperty(e => e.Target, "Target");
Map(e => e.Rate);
}
}
答案 0 :(得分:0)
我不确定您应该使用Source
方法映射Target
和KeyReference()
。我从来没有做过你在这里尝试做的事情,所以拿一些我写的东西。
我通常不使用自动映射功能,而是首选手动映射我的实体。在这些情况下,我Map()
枚举属性,而FNH使用NVARCHAR
类型。我指定了Length
和Not.Nullable()
。
因此,根据这些经验,我会尝试使用KeyProperty()
或Mapped()
,看看会发生什么。除此之外,搜索SO以查找复合ID问题,您将找到一篇文章,讨论使用实际复合类作为标识符,而不是实体本身的属性。
我还考虑手动映射这个类。