附加到上下文但无法删除它的实体

时间:2017-04-06 01:07:48

标签: c# entity-framework entity-framework-6

我在我的实体内部的方法中创建一个上下文来检查某些东西,但是我没有用它跟踪任何内容,但是当我尝试保存在调用代码上下文中时,它会引发异常。

这是我要保存的主要上下文中的调用代码:

var espToProcess = db.RootDomainEmailSeriesProgresses;

foreach (var esp in espToProcess)
{
    bool carryOn = esp.MoveNext();
    db.SaveChanges();   //Exception
    if (!carryOn) continue; 

    //--> rest of my code
}

这是RootDomainEmailSeriesProgress类中的方法。

public bool MoveNext()
{
    if (this.CompletedTargets == null) this.CompletedTargets = new List<EmailAddress>();

    if (this.CurrentTarget != null)
    {
        this.CompletedTargets.Add(this.CurrentTarget);
        this.CurrentTarget = null;
    }
    this.CurrentProgress = "";

    if (this.RootDomain.ContactFilter != RootDomain.ContactFilterType.None)
    {
        this.Status = EmailSeriesStatus.Aborted;
        return false;
    }

    var allTargets = RootDomainEmailManager.SortDomainsEmailsByDesirability(this.RootDomain.ID);
    var toDo = allTargets.Except(this.CompletedTargets);
    if (toDo.Count() < 1)
    {
        this.Status = EmailSeriesStatus.Completed;
        return false;
    }

    List<string> targetEmailList = allTargets.Select(e => e.Email).ToList();
    List<EmailFilter> emailFilters = this.GetFilters(allTargets);

    if (emailFilters.Any(x => x.Filter == EmailFilterType.Unsubscribe || x.Filter == EmailFilterType.Responded || x.Filter == EmailFilterType.ManualContactOnly))
    {
        this.Status = EmailSeriesStatus.Aborted;
        if (this.RootDomain.ContactFilter == 0) this.RootDomain.ContactFilter = RootDomain.ContactFilterType.HasAssociatedEmailFilter;
        return false;
    }

    this.CurrentTarget = toDo.First();

    return true;

}

private List<EmailFilter> GetFilters(List<EmailAddress> allTargets)
{
    using (var db = new PlaceDBContext())
    {
        db.Configuration.AutoDetectChangesEnabled = false;
        db.Configuration.LazyLoadingEnabled = false;

        var targetEmailList = allTargets.Select(e => e.Email).ToList();
        return db.EmailFilters.AsNoTracking().Where(x => targetEmailList.Contains(x.Email)).ToList();

    }
}

它抛出了这个异常:

  

无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象。

我无法理解为什么esp会附加到其他上下文。我只需要简单地介绍一下这个背景,我如何将其删除,以免导致我出现问题?

1 个答案:

答案 0 :(得分:0)

因为foreach循环和GetFilters方法中的DbContext实例存在差异

您可以重试此代码

var espToProcess = db.RootDomainEmailSeriesProgresses;

foreach (var esp in espToProcess)
{
    bool carryOn = esp.MoveNext(db);
    db.SaveChanges();   //Exception
    if (!carryOn) continue; 

    //--> rest of my code
}


public bool MoveNext(DbContext db)
{
    if (this.CompletedTargets == null) this.CompletedTargets = new 
List<EmailAddress>();

    if (this.CurrentTarget != null)
    {
        this.CompletedTargets.Add(this.CurrentTarget);
        this.CurrentTarget = null;
    }
    this.CurrentProgress = "";

    if (this.RootDomain.ContactFilter != RootDomain.ContactFilterType.None)
    {
        this.Status = EmailSeriesStatus.Aborted;
        return false;
    }

    var allTargets = 
RootDomainEmailManager.SortDomainsEmailsByDesirability(this.RootDomain.ID);
    var toDo = allTargets.Except(this.CompletedTargets);
    if (toDo.Count() < 1)
    {
        this.Status = EmailSeriesStatus.Completed;
        return false;
    }

    List<string> targetEmailList = allTargets.Select(e => e.Email).ToList();
    List<EmailFilter> emailFilters = this.GetFilters(allTargets, db);

    if (emailFilters.Any(x => x.Filter == EmailFilterType.Unsubscribe || 
x.Filter == EmailFilterType.Responded || x.Filter == 
EmailFilterType.ManualContactOnly))
    {
        this.Status = EmailSeriesStatus.Aborted;
        if (this.RootDomain.ContactFilter == 0) 
this.RootDomain.ContactFilter = 
RootDomain.ContactFilterType.HasAssociatedEmailFilter;
        return false;
    }

    this.CurrentTarget = toDo.First();

    return true;

}

private List<EmailFilter> GetFilters(List<EmailAddress> allTargets, DbContext db)
{
    db.Configuration.AutoDetectChangesEnabled = false;
    db.Configuration.LazyLoadingEnabled = false;

    var targetEmailList = allTargets.Select(e => e.Email).ToList();
    return db.EmailFilters.AsNoTracking().Where(x => 
targetEmailList.Contains(x.Email)).ToList();

}