【问题标题】:How can I remove an object and its children with Entity Framework?如何使用 Entity Framework 删除对象及其子对象?
【发布时间】:2016-05-18 16:44:02
【问题描述】:

我正在尝试使用 EF 删除一个对象和其他一些子对象。这是我正在使用的方法:

public async Task<IHttpActionResult> Delete([FromBody]WordForm wordForm)
{
    var olddObj = db.WordDefinitions
    .Where(w => w.WordFormId == wordForm.WordFormId)
    .AsNoTracking()
    .ToList();
    foreach (var wordDefinition in olddObj)
    {
        db.WordDefinitions.Attach(wordDefinition);
        db.WordDefinitions.Remove(wordDefinition);
    }
    db.WordForms.Attach(wordForm);
    db.WordForms.Remove(wordForm);
    await db.SaveChangesAsync();
    return Ok();
}

谁能向我解释为什么我会收到这条消息:

附加“Entities.Models.Core.WordDefinition”类型的实体 失败,因为相同类型的另一个实体已经具有相同的 主键值。使用“附加”方法或 将实体的状态设置为“未更改”或“已修改”(如果有) 图中的实体具有冲突的键值。这可能是因为 一些实体是新实体,尚未收到数据库生成的密钥 价值观。在这种情况下,使用“添加”方法或“添加”实体状态 跟踪图,然后将非新实体的状态设置为 “未更改”或“已修改”(视情况而定)。

这是对象定义:

public class WordForm 
{
    public string WordFormId { get; set; } // WordFormId (Primary key) (length: 20)
    public int WordFormIdentity { get; set; } // WordFormIdentity

    // Reverse navigation
    public virtual System.Collections.Generic.ICollection<WordDefinition> WordDefinitions { get; set; } // WordDefinition.FK_WordDefinitionWordForm

    public WordForm()
    {
        WordDefinitions = new System.Collections.Generic.List<WordDefinition>();
    }
}

【问题讨论】:

标签: asp.net entity-framework asp.net-web-api


【解决方案1】:

您的方法的第一部分已经在从查询返回时将对象加载到图中,因此无需附加它们。只需删除已加载的对象。第二个附加应该可以正常工作,但它也可以使用其主键将其加载到图表中然后将其删除。

这是您方法的重构版本...

public async Task<IHttpActionResult> Delete([FromBody]WordForm wordForm) {
    if(wordForm == null) return BadRequest();
    var toRemove = db.WordForms.FirstOrDefault(w => w.WordFormId == wordForm.WordFormId);
    if(toRemove != null) {
        var olddObj = db.WordDefinitions
        .Where(w => w.WordFormId == wordForm.WordFormId)
        .ToList();
        //removing children
        foreach (var wordDefinition in olddObj) {
            db.WordDefinitions.Remove(wordDefinition);
        }
        //remove parent object
        db.WordForms.Remove(toRemove);
        await db.SaveChangesAsync();
        return Ok();
    }
    return NotFound();
}

【讨论】:

  • 谢谢。它有效,但我只需要做一件小事就是删除 .AsNoTracking :-)
【解决方案2】:

我知道这可能不是您想要的解决方案,但您可以将数据库中的“删除规则”设置为“级联”,每当您删除一个对象时,它的所有子对象都将被删除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多