2010-11-12 21 views
62

DstContext nesnesinde ObjectContext için olduğu gibi neden bir Detach yöntemi bulunmadığını merak ediyorum. Bu ihmalin yalnızca kasıtlı olduğunu varsayabilirim, ama nedenini anlamakta zorlanıyorum. Varlıkları ayırıp yeniden ekleyebilmem gerekir (örneğin, bir ASP.NET projesinde önbelleğe koymak için). Ancak, bir nesneyi ayıramayacağım için, önceki bir bağlamla ilişkilendirilmiş bir varlığı eklemeyi denediğimde, "Bir varlık nesnesinin birden çok IEntityChangeTracker örneği tarafından başvurulan olamaz" özel durumunu aldım.Varlık Çerçeve Kodu İlk - Hayır Detach() yöntemi DbContext'de

Buradaki kılavuz nedir? Bir şey mi eksik?

+0

kimse Has hakkında söylenecek bir şey: "Buradaki rehber nedir? Bir şeyi mi özlüyorum?" Kişisel olarak, yalnızca, kullanıcı arabiriminden gelen örneği kaydetmeden önce, bağlamdan bir varlığı okumak için bir çözüm ararken Detach'ı kullanmakla ilgileniyorum. Bu bana "Aynı anahtara sahip bir nesne, ObjectStateManager'da zaten var.ObjectStateManager, aynı anahtarla birden çok nesneyi izleyemiyor. " –

cevap

85

CTP5 ait artık ObjectContext almak için

((IObjectContextAdapter)context).ObjectContext 

yazmak gerekir.

+1

+1 Ayrıca System.Data.Entity – Pandincus

+0

+1'e başvurmanız gerekiyor Temiz, zarif, tek bir astar.Ayrıca, arabirimin burada özel olarak bulunduğunu da atmak istedim: System.Data.Entity.Infrastructure.IObjectContextAdapter ve Pandincus gibi evet System.Data.Entity'ye bir başvuru yapmalısınız – dyslexicanaboko

38

DBContext içten bir ObjectContext kullanır ve Kullanmak veya açığa böylece Hiç alt düzey API aşağı düşmesi gerekir ve bu durum burada gibi geliyor ihtimale özelliğini korumalı olarak EF ekibi bu kullanılabilir hale türetilmiş DBContext gerekli işlevsellik:

public class YourContext : DbContext 
{ 
    public void Detach(object entity) 
    { 
     ObjectContext.Detach(entity);    
    } 
} 

Sonra bir varlık ayırmak için kumandadan bu yöntemi çağırabilirsiniz.

İşte
public class YourContext : DbContext 
{ 
    public void ChangeObjectState(object entity, EntityState entityState) 
    { 
     ObjectContext.ObjectStateManager.ChangeObjectState(entity, entityState); 
    } 
} 

DBContext meta verilerinden benziyor nasıl:

Alternatif olarak, hatta daha zengin bir API olması değiştirebilirsiniz bu soruya takılmaları isteyebilecek kişilere, hem İçin

public class DbContext : IDisposable 
{  
    protected System.Data.Objects.ObjectContext ObjectContext { get; } 
    ... 
} 
+0

@Stacker, bu, yanıtın yukarıda seçilen yanıtta özetlenen döküm gerektirdiğinden, yani" DbContext "ifadesinin" ObjectContext "özelliğini veren 'IObjectContextAdapter' özelliğini kullanması nedeniyle yanıt değil. Aksi halde erişilemez 2 cevapları birleştirmek @ splite'ın cevabını – eudaimos

+1

altında değiştirir ChangeObjectState oldukça tembeldir, "cast ile lineer algoritma" kullanarak ... Sıra ... Biliyorsunuz ... Reeeeally bad. –

15

EF: CF 4.1 RC1 ve EF: CF 4.1 RTW aynı açıkça uygulanır IObjectContextAdapter vardır:

public static class DbContextExtensions 
{ 
    public static void Detach(this System.Data.Entity.DbContext context, object entity) 
    { 
     ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.Detach(entity); 
    } 
} 

Microsoft karar "Ayır çok gelişmiş bir teknoloji ve gizli olmalıdır". IMHO bunu icat eden adam vurulmalı - çünkü yeni bir varlık eklediyseniz, db'de değişiklikler yapmadan onu kaldırmak zordur (DbEntityEntry ile manipüle edebilirsiniz ama bu başka bir hikaye). Daha sonra

Düzenleme 4 yıl:

Ef6'yıile EF4'ü gibi delete from [table] where [Id] = 0 oluşturmaz taze eklenen giriş çıkarmadan nedeniyle bu derste artık sen detach() ihtiyacım yok (i nasılsa F5'i :) atlanır) - sadece mySet.Remove(myFreshlyCreatedAndAddedEntity) arayabilir ve herşey yoluna girecek.

+0

shot? bu özelliğe kimin ihtiyacı var ?: P – quetzalcoatl

+1

@quetzalcoatl: 'var context = ...; var poco = yeni Poco(); context.Add (poco); context.Remove (poco); '--- --- istisnai bir istisna atar, onu kaldırırsınız, kaldırmaz - hey, çıkartma gizlidir ... –

+1

(düzenleme için 5 dk gitti, sry :)) O zamanlar öfkeli ... Windows uygulaması yaparken, "yeni, muhtemelen tamamlanmamış giriş yaratmayı ama UoW içeriğini korumayı" iptal etmenin bir yolunun olması gerekiyor ... Bütün EF btw'lerinden kurtulduk ve kendi ORM'imizi yazdık: tembel yükleme kullanmak için hiçbir yol (Ben faturalar demet var ve her InvoiceItem tek tek "InvoiceId yükleyebilirsiniz (xxyy) sorgu" - Dahil değil beklediğimiz şekilde çalışmaz), büyük depolar sooooo tembel (doğrusal (!!!)) her yürütmeden önce arama, wtf ...), 100+ poco türleri için proxy'ler oluşturmak çok fazla zaman alır ve bu yüzden ... –

6

Genellikle özelliğiyle temel sınıf (DBContext devralır) uzatmak:

public class MyDbContext : DbContext 
{ 
    public ObjectContext ThisObjectContext 
    { 
     get 
     { 
      return ((IObjectContextAdapter)this).ObjectContext; 
     } 
    } 
} 

ilerde faydalı şeyler çeşitli bu özelliği kullanabilirsiniz ... Ayırma gibi :)

İlgili konular