我在尝试阅读记录时一直在与EF斗争,然后在同一个交易中删除这些记录。我最初使用的是EntityState.Deleted方法,它会产生错误:
操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
但是如果我把它改成我下面的那个,使用.Remove(),那么一切都很好。
这是有问题的方法。请注意,我确实有一个使用.Deleted方法的通用存储库,该方法在此方案之前一直很好用(读取然后删除相同的记录。)
//Delete Allocation Need and AllocatedContainers for alloc need id
public ActionConfirmation<int> DeleteAllocRecords(int intFacilityId, AllocNeedSourceTypes needSourceType, int intNeedSourceId)
{
var context = new InventoryMgmtContext();
var repository = new AllocationNeedRepository(context);
//Delete Allocation Need and hence children in Allocated Containers
var srcType = needSourceType.ToString();
List<AllocationNeed> allocNeeds = repository.SearchFor(
x => x.FacilityId == intFacilityId
&& x.NeedSourceType == srcType
&& x.NeedSourceId == intNeedSourceId
).ToList();
//var deleteRepository = new Repository<AllocationNeed>(); <--tried separate instance of context to delete...no worky.
foreach (AllocationNeed allocNeed in allocNeeds)
{
try
{
//NO WORK: context.Entry(allocNeed).State = System.Data.EntityState.Deleted;
context.AllocationNeeds.Attach(allocNeed);
context.AllocationNeeds.Remove(allocNeed); <-- Works
context.SaveChanges();
}
catch (Exception ex)
{
return ActionConfirmation<int>.CreateFailureConfirmation(ex.Message, allocNeed.Id);
}
}
答案 0 :(得分:6)
Remove
也会移除子对象,但使用Deleted
则不会。出于这个原因,你应该真的使用Remove
。如果你真的想要使用Deleted
,你必须使你的外键可以为空,但是你最终会得到孤立的记录(这是你不应该使用的主要原因之一)首先要做的就是这样做。
答案 1 :(得分:2)
1.。)使用的区别和最佳时间是什么.Remove()vs .Deleted?
看起来将实体的状态设置为Deleted会导致SaveChanges()仅从数据库中删除该特定实体,而不考虑可能通过非空外键列引用它的其他行。
Remove()
将考虑作为关系一部分的行。
2.。)如何使用.Deleted方法完成此工作?
如果为相关行指定了ON CASCADE DELETE
行为,则数据库应自动处理。当您让EF生成数据库时,这是默认行为。