执行删除级联时的问题

时间:2017-01-07 13:55:29

标签: c# entity-framework repository-pattern unit-of-work

我有非常奇怪的情况要解决。 当我按ID删除对象时 - 每个想法都有效 当我将子项加载到Document(意味着DocumentPosition)并删除Document然后我得到了.NET异常

我有层次结构

  • 文档
    • DocumentPosition
      • DocumentResource
        • DocumentPackage

所有都用关系映射

  HasRequired(t => t.Document)
      .WithMany(t => t.DocumentPositions)
      .HasForeignKey(t => t.DocumentId);


public class Document : Entity
    {
        public Document()
        {
            DocumentPositions = new List<DocumentPosition>();
        }

        public int DocumentId { get; set; }
        public virtual ICollection<DocumentPosition> DocumentPositions { get; set; }
    }

public class DocumentPosition : Entity
    {
        public DocumentPosition()
        {
            DocumentResources = new List<DocumentResource>();
        }

        public int DocumentPositionId { get; set; }
        public int DocumentId { get; set; }
        public virtual Document Document { get; set; }
}

        private void SyncObjectsStatePreCommit()
        {
            foreach (var dbEntityEntry in ChangeTracker.Entries())
            {
                ** dbEntityEntry.State = StateHelper.ConvertState(((IObjectState)dbEntityEntry.Entity).ObjectState);
            }
        }
实体DocumentPosition上的

(当前标记为已修改,我们使用未修改覆盖它会导致.NET异常

  

“操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。“,

另外。 DocumentPosition在_entityWpithConceptualNulls中也是可见的,也在_modifiedEntityStore中。

我正在使用
URF - 工作单位&amp; (可扩展/通用)存储库框架 来自link to framework

我想在EF中实现级联删除。

Visual Studio cut

备注

dbEntityEntry.State等于修改

dbEntityEntry.Entity).ObjectState)等于未更改

回答@ Gert-Arnold 在SaveChanges之前运行SyncObjectsStatePreCommit

我有两种情况:   在我加载子项之前,通过 ID 或实体删除对象时,它就可以了。 虽然我已加载子项然后删除parent(将Entity.State设置为Deleted),然后将EntityFramework设置为父项的每个子ID为NULL。从逻辑上看这是正确的,但奇怪的情况是我在普通EntityFramework _context上执行这个场景。然后EntityFramework为每个孩子设置“神奇地”删除。

这是我的代码

public override void Delete(Document document)
{
    RemoveDocumentRelations(document); (load childrens)
    base.Delete(document);
}

它不起作用,但不同顺序的相同代码有效,

public override void Delete(Document document)
{
    base.Delete(document);
    RemoveDocumentRelations(document); (load childrens)
}

protected void DocumentRevertOutOptimaWrapper(Document document)
{
    var documentPositions = _repository.GetRepository<DocumentPosition>()
        .Queryable()
        .Where(position => position.DocumentId == document.DocumentId);
    foreach (var documentPosition in documentPositions)
    {
        var documentResources = _repository.GetRepository<DocumentResource>()
            .Queryable()
            .Where(resource => resource.DocumentPositionId == documentPosition.DocumentPositionId);
        foreach (var documentResource in documentResources)
        {
            var documentPackages = _repository.GetRepository<DocumentPackage>()
                .Queryable()
                .Where(package => package.DocumentResourceId == documentResource.DocumentResourceId);
            StockService.RestoreResourceOut(documentResource.ResourceId, documentResource.Quantity);
            foreach (var documentPackage in documentPackages)
                StockService.RestorePackageOut(documentPackage.PackageId, documentPackage.Quantity);
        }
    }
}

public virtual void Delete(TEntity entity)
{
    entity.ObjectState = ObjectState.Deleted;
    _dbSet.Attach(entity);
    _context.SyncObjectState(entity);
}

DataContext from framework

0 个答案:

没有答案