gpt4 book ai didi

c# - 无法更改关系,因为一个或多个外键属性不可为空

转载 作者:太空狗 更新时间:2023-10-29 19:42:49 28 4
gpt4 key购买 nike

(注意:这不是 this question 的副本,尽管它有相同的异常(exception)。)

我有一个穷人的交易,策略是:

  1. 插入父子记录。
  2. 执行长时间运行的操作。
  3. 如果长时间运行的操作失败,则去删除之前插入的父子记录。

当我尝试第 3 步时,我收到以下消息:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

我大体上理解这意味着什么,但我认为我是在遵守规则,无论我多么努力地遵守规则,我都不确定为什么我会收到这条消息。

我们使用 self 跟踪实体,我的代码实际上是这样的:

var parent = new Parent(1,2,3);
var child = new Child(4,5,6);
parent.Children.Add(child);

MyContext.Parents.ApplyChanges(parent);
MyContext.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);

// At this point, inserts were successful and entities are in an Unchanged state.
// Also at this point, I see that parent.Children.Count == 1

var shouldDeleteEntities = false;
try
{
// This is not database-related. This process does some
// encryption/decryption and uploads some files up to
// Azure blob storage. It doesn't touch the DB.
SomeLongRunningProcess();
}
catch
{
// Oops, something bad happened. Let's delete the entities!
shouldDeleteEntities = true;
}

// At this point, both entities are in an Unchanged state, child still
// appears in parent.Children, nothing is wrong that I can see.
parent.MarkAsDeleted();
child.MarkAsDeleted();

// I've tried MyContext.ApplyChanges here for both entities, no change.

// At this point, everything appears to be in the state that
// they're supposed to be!
try
{
MyContext.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
}
catch
{
// This exception was thrown and I can't figure out why!
}

这个逻辑有什么问题?为什么我不能简单地删除这两条记录?我试过在调用 MarkAsDeleted 之后调用 MyContext.ApplyChanges。我已经尝试了各种各样的事情,无论如何,无论我多么努力地告诉 Context 我想要删除它们both,它都会一直抛出这个异常。

最佳答案

@Slauma在上面的评论中提供了这个答案,但要求我发布答案。

问题是 Entity Framework 的 self 跟踪实体模板中实际上存在一个“错误”(Microsoft 不再建议您使用)。专门针对此主题的博客文章可以是 found here .

具体来说,问题在于 Context 的 ObjectStateManager 与(附加的)实体的 ChangeTracker.State 不同步,您最终会得到带有 的对象entity.ChangeTracker.State == ObjectState.Deleted 但当 context.ObjectStateManager 认为状态设置为 EntityState.Unchanged 时。这两者显然非常不同。因此,此修复程序有效地查找附加到作为 EntityState.Unchanged 的上下文的任何对象,但深入挖掘并检查每个对象的 ChangeTracker.State 是否有 ObjectState。已删除以修复问题。

可以在 Context 的 T4 模板中通过将 #region Handle Initial Entity State block 替换为以下代码:

#region Handle Initial Entity State

var existingEntities = context
.ObjectStateManager
.GetObjectStateEntries(System.Data.EntityState.Unchanged)
.Select(x => x.Entity as IObjectWithChangeTracker)
.Where(x => x != null);

var deletes = entityIndex.AllEntities
.Where(x => x.ChangeTracker.State == ObjectState.Deleted)
.Union(existingEntities
.Where(x => x.ChangeTracker.State == ObjectState.Deleted));

var notDeleted = entityIndex.AllEntities
.Where(x => x.ChangeTracker.State != ObjectState.Deleted)
.Union(existingEntities
.Where(x => x.ChangeTracker.State != ObjectState.Deleted));

foreach (IObjectWithChangeTracker changedEntity in deletes)
{
HandleDeletedEntity(context, entityIndex, allRelationships, changedEntity);
}

foreach (IObjectWithChangeTracker changedEntity in notDeleted)
{
HandleEntity(context, entityIndex, allRelationships, changedEntity);
}

#endregion

关于c# - 无法更改关系,因为一个或多个外键属性不可为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15993468/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com