【问题标题】:EF : why child records are not deletedEF:为什么不删除子记录
【发布时间】:2018-02-15 19:13:01
【问题描述】:

我有以下结构:

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);

然后我尝试从 ProblemSyncToVistracksDriver 中删除具体驱动程序的记录:

        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();

没有错误,所有其他更改都会保存。但是没有删除 ProblemSyncToVistracksDriver 中的记录。为什么以及如何解决?

【问题讨论】:

  • 将 WillCascadeOnDelete 设置为 true
  • @LucianBumb,无法将 WillCascadeOnDelete 设置为 true(客户要求)。
  • 该设置负责删除孩子的,如果你不能使用它意味着你需要在你的代码中手动执行
  • @LucianBumb 但字符串 driver.ProblemSyncToVistracksDriver = null;不是说手动删除吗?

标签: c# entity-framework entity-framework-6 ef-code-first code-first


【解决方案1】:

要删除子记录,您需要先从数据库中获取它,然后将其设置为 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();

您可以在这里找到更多解释similar question

【讨论】:

    【解决方案2】:

    在您的模型中,您指定:

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

    该规范表明每个ProblemSyncToVistrackDriver 对象恰好属于一个Driver,而不是零,不是两个:正好是一个。此驱动程序可在属性Driver 中找到。

    您将在属性Driver 中找到的驱动程序具有可选属性ProblemSyncToVistracksDriver。这意味着,如果该属性为空,实体框架可能会假定没有属于此DriverProblemSyncToVistrackDriver

    您所做的是指定了正确的一对零或一关系。每个Driver 有零个或一个ProblemSyncToVistrackDriver,每个ProblemSyncToVistrackDriver 恰好属于一个Driver

    如果你有一个Driver,并且你将它的ProblemSyncToVistrackDriver 设置为零,那么你的意思是这个Driver 不再有ProblemSyncToVistrackDriver。通常,CascadeOnDelete 会注意删除此Driver 的前ProblemSyncToVistrackDriver。您指定不希望自动删除,因此不会删除 ProblemSyncToVistrackDriver。这就是它没有被删除的原因。

    如果您指定要手动删除,则必须自己删除该项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      • 2011-08-31
      相关资源
      最近更新 更多