teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

訂正

2021/06/02 04:27

投稿

退会済みユーザー
answer CHANGED
@@ -48,7 +48,7 @@
48
48
 
49
49
  (2) 前のクエリで AsNoTracking を呼び出す
50
50
 
51
- 上記 (2) のように AsNoTracking を呼び出すことで例外は回避できます。以下の画像を見てください。
51
+ の画像の例外は、例えば上記 (2) の解決方法の AsNoTracking を呼び出すことで回避できます。以下の画像を見てください。
52
52
 
53
53
  ![イメージ説明](b8d6f41e872cd33bb548ae064cc80e92.jpeg)
54
54
 

1

追記

2021/06/02 04:27

投稿

退会済みユーザー
answer CHANGED
@@ -17,4 +17,39 @@
17
17
  Attaching an existing but modified entity to the context
18
18
  [https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state#attaching-an-existing-but-modified-entity-to-the-context](https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state#attaching-an-existing-but-modified-entity-to-the-context)
19
19
 
20
- お試しください。postgres は違うかもしれませんが、もし違ったらすみません。
20
+ お試しください。postgres は違うかもしれませんが、もし違ったらすみません。
21
+
22
+ **【追記】**
23
+
24
+ 下のコメント欄の 2021/06/02 11:10 の私のコメントで「質問者さんのエラーを再現してみました。後で回答欄にその画像を貼っておきます。」と書いた件です。
25
+
26
+ 先にコメント欄に書いたことも話を分かりやすくするためにまとめて書いておきます。
27
+
28
+ > おそらく_dataBaseService内にすでにidが存在しているのが原因のようですが更新時にユニークな値が必ず必要だという認識なのですよね
29
+
30
+ そうではなくて、質問に書いてない上の回答のコードの前にエンティティの取得とかしていて、当該エンティティが追跡中になっているからだと思います。
31
+
32
+ 自分の環境 .NET 5.0, EF Core 5.0, SQL Server でも以下のようにして再現できます。
33
+
34
+ ![イメージ説明](e38c943d7cf1d8ac25eb91dab3a7ee55.jpeg)
35
+
36
+ 以下の Microsoft のドキュメントを見てください。
37
+
38
+ 追跡なしのクエリ
39
+ [https://docs.microsoft.com/ja-jp/aspnet/core/data/ef-mvc/crud?view=aspnetcore-5.0#no-tracking-queries](https://docs.microsoft.com/ja-jp/aspnet/core/data/ef-mvc/crud?view=aspnetcore-5.0#no-tracking-queries)
40
+
41
+ 質問者さんの "The instance of entity type 'BooksData' cannot be tracked because another instance with the same key value for {'id'} is already being tracked." というエラーメッセージは、上記の記事に書いてあるように:
42
+
43
+ "エンティティを更新するためにエンティティをアタッチしたいが、それより前に別の目的で同じエンティティを取得してある場合。 エンティティはデータベース コンテキストによって既に追跡されているため、変更するエンティティをアタッチできません"
44
+
45
+ ・・・ということであろうと思われます。解決方法は、これも記事に書いてありますが以下の 2 つが考えられます。
46
+
47
+ (1) ASP.NET Core Web アプリケーションのように、エンティティを読み取るコンテキストをエンティティが再び使われる前に破棄
48
+
49
+ (2) 前のクエリで AsNoTracking を呼び出す
50
+
51
+ 上記 (2) のように AsNoTracking を呼び出すことで例外は回避できます。以下の画像を見てください。
52
+
53
+ ![イメージ説明](b8d6f41e872cd33bb548ae064cc80e92.jpeg)
54
+
55
+ ただ、この問題が解決できたとしても、tamoto さんの回答で言われている setter なしプロパティのエンティティクラスがホントに使えるかは疑問ですが。とにかく試してみてください。