SaveChanges上意外的ForeignKey更改

时间:2019-06-11 12:55:27

标签: c# .net entity-framework

当前,我正在尝试解决 EntityFramework 的难题,在SaveChanges

因此由于某些原因,以下代码片段决定将ReceiptEntry的值始终更改为10或12

void HandleReceipt(DBContext cntxt, Receipt receipt, ...)
{
    [...]
    var receiptEntries = receipt.GetEntries(cntxt);
    var receiptEntriesItem = from q in cntxt.Items
                             where ...
                             select new { ... };
    var receiptEntriesItemDictionary = receiptEntriesItem.ToDictionary(...);
    [...]
    while (...)
    {
        [...]
        var receiptEntry = receiptEntriesItemDictionary[it.ItemFK];
        [...]
        foreach (var kvp in ...)
        {
            var sle = usedStorages.First((sl) => sl.Id == kvp.Key);
            entry = new PickListEntry
            {
                Parent = receipt.PickList,
                Amount = kvp.Value,
                ReceiptEntry = receiptEntry, // receiptEntry is the instance with eg. Id 60
                StorageLocation = sle
            };
            sle.Stock = new Stock { AmountAvailable = 0, ItemFK = receiptEntry.ItemFK };
            var createdEntry = cntxt.PickListEntries.Add(entry);
            cntxt.SaveChanges(); // ReceiptEntry property gets modified in here to the instance with 10 or 12
            [...]
        }
        [...]
    }
}

到目前为止,我不知道为什么会发生这种情况。

10和12是与receipt上当前工作无关的条目(但是,它们已加载到当前的cntxt中,并在另一个对{{1}的调用中进行了处理) })

我已经三倍地检查了这两个字符从未分配到任何地方(条目仅在此处使用,以后再也没有在此处使用),并检查了它们何时被更改(著名的HandleReceipt恰好在二传手之下)< / p>

任何人都可以告诉我为什么会发生这种情况以及如何解决?旋转另一个[External Code]是不可行的,因为这是在事务(DBContext)内部发生的(又名:失败会导致一切都需要回滚)

1 个答案:

答案 0 :(得分:0)

实际的问题出在一个名为FlatCopy()的小方法的内部,有人实施了粗心的操作……

// Problematic, as there is a collection in here that gets refered to
public ReceiptEntry FlatCopy() => this.MemberwiseClone() as ReceiptEntry;

// Totally fine as we create a new collection
public ReceiptEntry FlatCopy()
{
    var copy = this.MemberwiseClone() as ReceiptEntry;
    copy.PicklistEntries = new ObservableCollection<PickListEntry>();
    copy.Id = 0;
    return copy;
}

然后,针对上述“奇怪”行为的实际推理是将其添加到其他ReceiptEntry的{​​{1}}集合中,然后导致PicklistEntries字段的更新。 / p>

TL; DR:尊敬的用户用户,请检查您的复制方法是否确实创建了集合的单独实例。