Skip to content
戻る

EntityFrameworkでテーブルがコミットされていなかった

Published:  at  02:31

概要

書いていたコードでテーブルに対してUPDATEをかけてCOMMITまでいってると思っていたら
UPDATE文が発行されておらずCOMMITもされていなかったメモ

対象のオブジェクトはオブジェクトの中にListを持っていて
EntityFrameworkので作成されるDBのテーブル的にはオブジェクト用のテーブルとさらにList用のテーブルの2つがあります。
2つまとめて1つのオブジェクトとして扱っていたのでUPDATE文が発行されていなかったオチです。

設計が悪いだのみたいなところには触れないでください。

目次

環境

事象

  1. ツイートを行う。このときのツイートをAとする。
  1. ツイートAに対して返信(リプライ)の形式でツイートBを飛ばす。
  1. 以下ツイートが増えるごとに2の繰り返し

上記の動きがイメージするものでしたがツイートIDが更新されず
何回ツイートしても一番最初にツイートされたツイートAにメンションされている状態となっていました。

登場人物(オブジェクト)

public class TweetResult
{
    public int id { get; set; } //EFにて自動でIndexが付与される
    public string userId { get; set; } //アプリケーション内でユーザを特定する一意のID
    public long tweetId { get; set; } //前述のツイートID
    public List<MyTask> myTasks { get; set; }
}
public class MyTask {
    public int id { get; set; }
    public string myTask { get; set; }
    public int state { get; set; }
    //EFの機能でTweetResultからMyTaskを特定するためのIDがテーブルに追加されている。
}
//タスクのステータス更新とツイートID(リプライ先)の更新
public int UpdateTask(TweetResult tr) {
    using (MyContext db = new MyContext()) {
        var tresult = db.TweetResults.Where(x => x.id == tr.id)
                                 .Include("MyTasks")
                                 .SingleOrDefault();
        tresult = tr; //問題の部分
        db.SaveChanges(); //コミット
        return 0;   //正常終了値のつもり
    }
}

TweetResultテーブルから件のレコードを特定し、引数で渡されたオブジェクトを突っ込んで
そのままコミットしている”つもり”でした。

デバッグ画面でオブジェクトにちゃんと引数で渡しているオブジェクトに新しいツイートIDを入れていて値も確認しているのに更新された値は元のままで「なんでだ????」状態でした。

SQLログを確認したところUPDATE文が発行されていませんでした。
ここでハッと気付き、テーブルが2つあるからUPDATE文が発行されていない説を試しました。

メモ:SQLログの確認方法

下記を任意の場所に記述

db.Database.Log = (log) => Debug.WriteLine(log);

参考:http://tsubalog.hatenablog.com/entry/2015/07/06/110000 🔗

//タスクのステータス更新とツイートID(リプライ先)の更新
public int UpdateTask(TweetResult tr) {
    using (MyContext db = new MyContext()) {
        var tresult = db.TweetResults.Where(x => x.id == tr.id)
                                 .Include("MyTasks")
                                 .SingleOrDefault();
        tresult.myTasks = tr.myTasks; //修正
        tresult.tweetId = tr.tweetId; //修正
        db.SaveChanges(); //コミット
        return 0;   //正常終了値のつもり
    }
}

上記コードのようにテーブルごとにデータを格納したところ
以下のようなログが発行されコミットが確認出来ました。

2018/04/25 1:19:10 +09:00 で接続を開きました
2018/04/25 1:19:10 +09:00 でトランザクションを開始しました
UPDATE [dbo].[MyTasks]
SET [TweetResult_id] = NULL
WHERE (([id] = @0) AND ([TweetResult_id] = @1))
...省略
-- 1 ミリ秒で完了しました。結果: 1
UPDATE [dbo].[TweetResults]
SET [tweetId] = @0
WHERE ([id] = @1)
...省略
-- 0 ミリ秒で完了しました。結果: 1
...省略
2018/04/25 1:19:10 +09:00 でトランザクションをコミットしました
2018/04/25 1:19:10 +09:00 で接続を閉じました

テーブルデータの確認も行い
Twitterにてメンションが連なる様子も実際に確認できました。

https://twitter.com/Lychee_jam/status/988815281005867008 🔗

参考サイト様

雑感

デバッグ画面でちゃんと値が入ってんのになんだこりゃー状態でしたがログを確認するのも大事ですね。



前の記事
ASP.NET Viewページにツイートを埋め込む(oEmbed)
次の記事
C# CoreTweetのTutorialを少しやった