操作失败:由于一个或多个外键属性为非空,因此无法更改关系。

5

这些是我的实体:

public class Currency : Exchange
{
     public List<CurrencyPrice> CurrencyPrice { get; set; }
}

public class CurrencyPrice : Price
{
    public int CurrencyId { get; set; }
    [ForeignKey("CurrencyId")]
    public Currency Currency { get; set; }
}

第一次向数据库插入值时,一切正常,但如果我更改了数据库中的任何值,并尝试插入或更新记录,则会出现以下错误:
“操作失败:由于一个或多个外键属性是非空的,因此无法更改关系。当关系发生变化时,相关的外键属性被设置为 null 值。如果外键不支持 null 值,则必须定义新关系,将外键属性分配为另一个非 null 值,或删除不相关的对象。”
这是我的插入代码:
var currency =
    UnitOfWork.Exchange.Get(x => x is Currency && x.ExchangeType.Id == exchangeTypeId) as Currency;
if (currency != null)
{
    CurrencyPrice lastPriceValue = UnitOfWork.CurrencyPrice.Last(x => x.CurrencyId == currency.Id);
    if (lastPriceValue == null || lastPriceValue.Value != price)
    {
        currency.CurrencyPrice = new List<CurrencyPrice>
            {
                new CurrencyPrice {Id = Guid.NewGuid().ToString(), EntryDate = DateTime.Now, Value = price,CurrencyId = currency.Id,Currency = currency}
            };
    }
    else
    {
        lastPriceValue.EntryDate = DateTime.Now;
    }

    UnitOfWork.Commit();
}

我在StackOverflow上搜索并找到了这个。但是我不理解我需要做什么。

2个回答

10

我认为问题出在这段代码块中:

currency.CurrencyPrice = new List<CurrencyPrice>
{
    new CurrencyPrice {Id = Guid.NewGuid().ToString(), EntryDate = DateTime.Now, Value = price,CurrencyId = currency.Id,Currency = currency}
};

在这里,您创建了一个新的 CurrencyPrice 并将其分配给一个 Currency,因此使之前分配给该 CurrencyCurrencyPrice 对象变成了孤儿对象。这个对象现在仍然存在于数据库中,但没有父级。因此 EntityFramework 希望在这个 CurrencyPrice 上设置父级的 ID 为 NULL,但是数据库会阻止这样做,导致产生您引用的错误。我在这个答案中发布了更详细的解释。

为了避免这种情况发生,在添加新的 CurrencyPrice 之前从数据库中删除旧的 CurrencyPrice。或者,由于似乎 CurrencyPrice 对象始终依赖于它们的 Currency 父级,您可以考虑将其作为标识关系。我已经解释了如何使用 EntityFramework 4 Model First 创建它们,详情请参见Implementing identifying relationships with EF4。我还没有使用 Code First,但是方法应该类似。


非常感谢您。我遇到了完全相同的问题,但我的解决方案最终是只更改列表的值而不是创建一个全新的并替换它。希望错误描述能够更详细一些;让我困惑了数小时... - Nicholas Siegmundt

0
当在上下文中保存更改时遇到相同错误,并且未对实体或关系进行任何更改。
错误是因为某些实体覆盖了 GetHashCode() 方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接