Consider the following entity model:
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; }
}
The reason there is not a direct ICollection<Establishment>
on the Agreement entity is because of the IsOwner property, which further defines this many-to-many relationship.
The relationship is mapped like so:
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);
}
The relationship is uni-directional, meaning you can only get to the Participants from within an Agreement -- you cannot access the agreements from the Establishment.
Now, since the Agreement entity's primary key is part of the gerund Participant's primary key, and since cascade delete is specified, I would expect that putting the Agreement into the Deleted state would also cause each entity in its Participants collection to also be put into the deleted state.
This appears to work when calling Remove on an Agreement DbSet:
// this works
dbContext.Agreements.Remove(agreement);
dbContext.SaveChanges();
However, it does not appear to work when simply setting the agreement entry's state to deleted:
// this causes an exception when Participants is not empty
dbContext.Entry(agreement).State = EntityState.Deleted;
dbContext.SaveChanges();
Is there a way I can define the relationship so that simply putting the Agreement entity into the deleted state will also cause the corresponding collection item entities to be put into the deleted state?
Update
I have been reading about this, and found out that eager loading the Participants collection does not help:
// 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();
When you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.
EF API maintains the state of each entity during its lifetime. Each entity has a state based on the operation performed on it via the context class. The entity state represented by an enum System.
This can be achieved in several ways: setting the EntityState for the entity explicitly; using the DbContext. Update method (which is new in EF Core); using the DbContext. Attach method and then "walking the object graph" to set the state of individual properties within the graph explicitly.
Ended up solving this by calling the following:
dbContext.Set<Agreement>().Remove(agreement);
I wanted to get rid of the Agreements
property on the DbContext
, which is why I was trying to do it with Entry(agreement).State = EntityState.Deleted
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With