System.InvalidOperationException:试图添加属性' Name'什么时候添加

时间:2012-03-04 21:03:02

标签: nhibernate fluent-nhibernate

我真的很难让我的第一个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);
    }
}

1 个答案:

答案 0 :(得分:0)

我不确定您应该使用Source方法映射TargetKeyReference()。我从来没有做过你在这里尝试做的事情,所以拿一些我写的东西。

我通常不使用自动映射功能,而是首选手动映射我的实体。在这些情况下,我Map()枚举属性,而FNH使用NVARCHAR类型。我指定了LengthNot.Nullable()

因此,根据这些经验,我会尝试使用KeyProperty()Mapped(),看看会发生什么。除此之外,搜索SO以查找复合ID问题,您将找到一篇文章,讨论使用实际复合类作为标识符,而不是实体本身的属性。

我还考虑手动映射这个类。