前回のデータの設定の記事で紹介したForm1画面のデータ読込を押した時の処理を書いて行きます。

private void buttonRead_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
var lists = _dbContext.Books.ToList();
foreach (var data in lists)
{
string[] item1 = new string[2];
item1[0] = data.BookName;
if (data.Category != null)
{
item1[1] = data.Category.CategoryName;
}
listView1.Items.Add(new ListViewItem(item1));
}
}
この読込ボタンは一度アプリを再起動して読込ボタンを押してみてください。上記コードの「if (data.Category != null)」ここの個所がnullになっている為、カテゴリー名が表示されません。

これもかなりハマりましたが、上記関数の先頭にこの一文を加えてみます。「var categoryList = _dbContext.BookCategorys.ToList();」
今度はカテゴリー名がちゃんと入っていました。

次に、この一文を「var categoryList = _dbContext.BookCategorys.ToList();」次のように変えてみます。「var categoryList = _dbContext.BookCategorys.AsNoTracking().ToList();」
EntityFrameworkではDBContextが管轄しているデータのどこに変更があったかを管理している追跡機能というのがあります。AsNoTrackingとは、これを無効にする操作らしいです。読み取り専用の場合、これをつけておくとデータの取得時間が速くなるそうです。では、これでやってみるとカテゴリーはnullになってしまいます。

AsNoTrackingをつけてマスタのリストを取得すると、モデルクラスの子テーブルに反映されません。また、AsNoTrackingをつけていた場合、アプリの起動中にアプリのコード上からではなく、直接マスタテーブルの情報を書き換えた場合、その変更情報は取得できますが、 AsNoTrackingをつけていなかった場合、アプリを再起動しない限りマスタテーブルの変更情報は反映されません。
ここら辺分かってないと、使いこなすの難しいですよね。。Book2の方は以下のようにしてAsNoTrackingをつけて取得した場合でも、マスターのデータはidのみなので取得する事ができます。
private void buttonRead2_Click(object sender, EventArgs e)
{
listView2.Items.Clear();
var categoryList = _dbContext.BookCategorys.ToList();
var lists = _dbContext.Book2s.AsNoTracking().ToList();
foreach (var data in lists)
{
string[] item1 = new string[2];
item1[0] = data.BookName;
var category = _dbContext.BookCategorys.FirstOrDefault(a => a.CategoryID == data.CategoryID);
if (category != null)
{
item1[1] = category.CategoryName;
}
listView2.Items.Add(new ListViewItem(item1));
}
}