Saya mendapatkan kesalahan berikut saat mencoba melampirkan objek yang sudah dilampirkan ke konteks tertentu melalui context.AttachTo(...)
:
Objek dengan kunci yang sama sudah ada di ObjectStateManager. ObjectStateManager tidak dapat melacak banyak objek dengan kunci yang sama.
Adakah cara untuk mencapai sesuatu di sepanjang garis:
context.IsAttachedTo(...)
Bersulang!
Edit:
Metode ekstensi yang dijelaskan Jason sudah dekat, tetapi tidak berhasil untuk situasi saya.
Saya mencoba melakukan beberapa pekerjaan menggunakan metode yang diuraikan dalam jawaban untuk pertanyaan lain:
Kode saya terlihat seperti ini:
var user = new User() { Id = 1 };
context.AttachTo("Users", user);
comment.User = user;
context.SaveChanges();
Ini berfungsi dengan baik, kecuali ketika saya melakukan sesuatu yang lain untuk pengguna itu di mana saya menggunakan metode yang sama dan mencoba melampirkan User
objek dummy . Ini gagal karena saya sebelumnya telah melampirkan objek pengguna dummy itu. Bagaimana saya bisa memeriksa ini?
sumber
(T)entry.Entity
terkadang mengembalikan nol?T
sudahIEntityWithKey
, tidak bisakah Anda menggunakanentity.EntityKey
propertinya daripada merekonstruksinya atau perlu menebak / memberikanEntitySetName
?Pendekatan yang lebih sederhana adalah:
bool isDetached = context.Entry(user).State == EntityState.Detached; if (isDetached) context.Users.Attach(user);
sumber
.Include()
properti navigasi juga dicoba untuk dilampirkan ketika Anda memanggil.Attach
atau menyetelnyaEntityState
keEntityState.Unchanged
- dan mereka akan konflik jika ada entitas yang merujuk ke entitas yang sama. Saya belum menemukan cara untuk hanya melampirkan entitas dasar, jadi saya harus mendesain ulang proyek sedikit, untuk menggunakan konteks terpisah untuk setiap "transaksi bisnis", seperti yang dirancang untuk itu. Saya akan mencatat ini untuk proyek mendatang.Coba metode ekstensi ini (ini belum teruji dan tidak langsung):
public static bool IsAttachedTo(this ObjectContext context, object entity) { if(entity == null) { throw new ArgumentNullException("entity"); } ObjectStateEntry entry; if(context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry)) { return (entry.State != EntityState.Detached); } return false; }
Mengingat situasi yang Anda gambarkan dalam pengeditan, Anda mungkin perlu menggunakan kelebihan beban berikut yang menerima
EntityKey
alih - alih objek:public static bool IsAttachedTo(this ObjectContext, EntityKey key) { if(key == null) { throw new ArgumentNullException("key"); } ObjectStateEntry entry; if(context.ObjectStateManager.TryGetObjectStateEntry(key, out entry)) { return (entry.State != EntityState.Detached); } return false; }
Untuk membangun
EntityKey
situasi Anda, gunakan yang berikut sebagai pedoman:EntityKey key = new EntityKey("MyEntities.User", "Id", 1);
Anda bisa mendapatkan
EntityKey
dari instance yang adaUser
dengan menggunakan propertiUser.EntityKey
(dari antarmukaIEntityWithKey
).sumber
TryGetObjectStateEntry
yang menerima danEntityKey
bukannyaobject
. Saya telah mengeditnya. Beri tahu saya jika ini tidak membantu dan kita akan kembali ke papan gambar.Menggunakan kunci entitas dari objek yang Anda coba periksa:
var entry = context.ObjectStateManager.GetObjectStateEntry("EntityKey"); if (entry.State == EntityState.Detached) { // Do Something }
Kebaikan,
Dan
sumber
Ini tidak secara langsung menjawab pertanyaan OP tetapi ini adalah bagaimana saya menyelesaikan pertanyaan saya.
Ini untuk mereka yang menggunakan,
DbContext
bukanObjectContext
.public TEntity Retrieve(object primaryKey) { return DbSet.Find(primaryKey); }
Metode DbSet.Find :
Pada dasarnya, ini mengembalikan objek terlampir yang diberikan
primaryKey
sehingga Anda hanya perlu menerapkan perubahan pada objek yang dikembalikan untuk mempertahankan contoh yang benar.sumber