0

I have the following structure:

public partial class Driver 
{
    public int ID { get; set; }
    //....

    #region Vistracks Required Fields

    public virtual ProblemSyncToVistracksDriver ProblemSyncToVistracksDriver { get; set; }

    #endregion
}


public partial class ProblemSyncToVistracksDriver
{
    [Key, ForeignKey("Driver")]
    public int DriverId { get; set; }
    public virtual Driver Driver { get; set; }

    public int? ResponseCode { get; set; }
    public string Message { get; set; }
    public string Description { get; set; }
    public bool IsServerError { get; set; }
    public DateTime DateAdded { get; set; }
}


modelBuilder.Entity<ProblemSyncToVistracksDriver>()
    .HasRequired(s => s.Driver)
    .WithOptional(ad => ad.ProblemSyncToVistracksDriver)
    .WillCascadeOnDelete(false);

then I try to remove a record from ProblemSyncToVistracksDriver for concrete driver:

        var driver = await (from i in _db.Drivers where i.AspNetUser.UserName.Equals(model.Email, StringComparison.InvariantCultureIgnoreCase) select i).FirstOrDefaultAsync();
        if (driver == null)
            throw new NullReferenceException();

        driver = mapper.Map<VistrackDriverInfoDomain, Infrastructure.Asset.Driver>(model, driver);
        driver.IsVistracksAdded = true;
        driver.VistracksDateSync = DateTime.Now;
        driver.ProblemSyncToVistracksDriver = null;

        _db.Entry(driver).State = EntityState.Modified;
        await _db.SaveChangesAsync();

no errors, all other changes are saved. But record in ProblemSyncToVistracksDriver is not deleted. Why and how to fix it?

Oleg Sh
  • 8,496
  • 17
  • 89
  • 159

2 Answers2

1

In order to remove a child record you need first to get it from database and then you can set it to null:

var driver=_db.Drivers.Include(x=>x.ProblemSyncToVistracksDrivers)
.FirstOrDefaultAsync(x=>x.AspNetUser.UserName.Equals(model.Email, StringComparison.InvariantCultureIgnoreCase));
driver.ProblemSyncToVistracksDriver = null;
 await _db.SaveChangesAsync();

more explanations you can find here similar question

Lucian Bumb
  • 2,821
  • 5
  • 26
  • 39
1

In your model, you specified:

modelBuilder.Entity<ProblemSyncToVistracksDriver>()
    .HasRequired(s => s.Driver)
    .WithOptional(ad => ad.ProblemSyncToVistracksDriver)
    .WillCascadeOnDelete(false);

This specification indicates that every ProblemSyncToVistrackDriver object belongs to exactly one Driver, not zero, not two: exactly one. This Driver can be found in property Driver.

The Driver that you will find in property Driver has an optional property ProblemSyncToVistracksDriver. This means, that if that property is null, entity framework might assume that there is no ProblemSyncToVistrackDriver that belongs to this Driver.

What you did, is that you specified a proper one-to-zero-ore-one relation. Every Driver has zero or one ProblemSyncToVistrackDriver, every ProblemSyncToVistrackDriver belongs to exactly one Driver.

If you've got a Driver, and you'll set its ProblemSyncToVistrackDriver to zero, then what you are saying is that this Driver has no ProblemSyncToVistrackDriver anymore. Normally, CascadeOnDelete would have taken care that the former ProblemSyncToVistrackDriver of this Driver would be deleted. You specified that you don't want this automatic deletion, hence the ProblemSyncToVistrackDriver is not deleted. That's why it is not deleted.

If you specify that you want manual-deletion, you'll have to delete the item yourself.

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116