DbSet.Remove和DbContext.Entry(entity)之间的区别.State = EntityState.Deleted

dan*_*wig 9 entity-framework entity-framework-4 entity-framework-4.1 entity-framework-4.2

考虑以下实体模型:

public class Agreement : Entity
{
    public int AgreementId { get; set; }
    public virtual ICollection<Participant> Participants { get; set; }
}

public class Establishment : Entity
{
    public int EstablishmentId { get; set; }
}

public class Participant : Entity
{
    public int AgreementId { get; set; }
    public virtual Agreement Agreement { get; set; }

    public int EstablishmentId { get; set; }
    public virtual Establishment { get; set; }

    public bool IsOwner { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

ICollection<Establishment>在协议实体上没有直接的原因是因为IsOwner属性,它进一步定义了这种多对多关系.

关系映射如下:

internal ParticipantOrm()
{
    ToTable(typeof(Participant).Name);

    HasKey(k => new { k.AgreementId, k.EstablishmentId });

    HasRequired(d => d.Agreement)
        .WithMany(p => p.Participants)
        .HasForeignKey(d => d.AgreementId)
        .WillCascadeOnDelete(true);

    HasRequired(d => d.Establishment)
        .WithMany()
        .HasForeignKey(d => d.EstablishmentId)
        .WillCascadeOnDelete(true);
}
Run Code Online (Sandbox Code Playgroud)

这种关系是单向的,这意味着您只能从协议中获得参与者 - 您无法访问企业的协议.

现在,由于协议实体的主键是动名词参与者的主键的一部分,并且由于指定了级联删除,我希望将协议置于已删除状态也会导致其参与者集合中的每个实体也被放入删除状态.

在协议DbSet上调用Remove时,这似乎有效:

// this works
dbContext.Agreements.Remove(agreement);
dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

但是,当简单地将协议条目的状态设置为已删除时,它似乎不起作用:

// this causes an exception when Participants is not empty
dbContext.Entry(agreement).State = EntityState.Deleted;
dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

有没有办法可以定义关系,这样简单地将协议实体置于已删除状态也会导致相应的集合项实体进入已删除状态?

更新

我一直在阅读这篇文章,并发现急切加载参与者集合并没有帮助:

// eager loading does not help, this still breaks
var agreement = dbContext.Set<Agreement>()
    .Include(a => a.Participants)
    .FirstOrDefault();
dbContext.Entry(agreement).State = EntityState.Deleted;
dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

dan*_*wig 15

通过调用以下内容结束解决此问题:

dbContext.Set<Agreement>().Remove(agreement);
Run Code Online (Sandbox Code Playgroud)

我想摆脱它的Agreements属性DbContext,这就是为什么我试图这样做Entry(agreement).State = EntityState.Deleted.

  • 我很想知道.Remove和设置entityState之间的区别.我观察到不同的行为并且发现.Remove()更加可靠 (2认同)