読者です 読者をやめる 読者になる 読者になる

Entity Framework でエンティティを削除したら取得済みエンティティの外部キーが null になっていてハマッた

.net

Id の型に int ではなく string を使った

public class Item
{
    public string Id { get; set; }
    public string ProjectId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

のようなエンティティで

public class ItemController : Controller
{
    // ...(省略)...

    [HttpPost]
    public async Task<ActionResult> Delete(string itemId)
    {
        var item = await DbContext.Items.FindAsync(itemId);

        DbContext.Items.Remove(item);
        await DbContext.SaveChangesAsync();

        return RedirectToAction("Index", new { projectId = item.ProjectId });
    }
}

という風に削除した後リダイレクトするコードを書いたら、リダイレクト失敗。 削除した時点で変数 itemProjectId プロパティ が null になってしまうことに気付かなくてハマッた。

今まで Id の型に int だけを使ってきたけど、そのときは ProjectId が 0 になるなんてことは無かった。 初めて string に変えてみたんだけど、まさか削除したら外部キーが null になるとはね。

デバッガで追ってみたけど、null になるのは外部キーの item.ProjectId だけで、 item.Iditem.Title は null になっていなかった。

とりあえず今回は、単純にリダイレクトに必要な値を、削除前に変数に保持しておくことで回避。

public class ItemController : Controller
{
    // ...(省略)...

    [HttpPost]
    public async Task<ActionResult> Delete(string itemId)
    {
        var item = await DbContext.Items.FindAsync(itemId);
        var projectId = item.ProjectId;

        DbContext.Items.Remove(item);
        await DbContext.SaveChangesAsync();

        return RedirectToAction("Index", new { projectId });
    }
}