2011-04-18 34 views
5

How to: Customize Generated Data Objects numaralı belgede açıklandığı gibi EntityFramework nesnelerim için uzantılar oluşturuyorum ancak bu uzantıların bazılarında, modeldeki diğer değerleri aramak için örneğin ObjectContext dosyasını edinmem gerekiyor. Ben Tip 24 – How to get the ObjectContext from an Entity buldum ama bu, bu similar SO question başvurulan bir kaç yıl önce yazılmıştı, ama şimdi daha iyi bir cevap var umuyordum.Nesne nesnesinden bir ObjectContext başvurusu almanın en hızlı yolu nedir?

Kuşkusuz bu, bir Kuruluşun nesne bağlamının kuruluştan alınmasının, resmi bir yöntemle desteklenmesi gerektiği sık sık ihtiyaç duyulan bir şey olmalı.

Bu uygulama hakkında daha yeni bilgi için şimdiden teşekkür ederiz.

cevap

0

Hayır böyle bir yöntem yoktur. Bildiğim kadarıyla

[Serializable, DataContract(IsReference=true)] 
public abstract class EntityObject : StructuralObject, IEntityWithKey, 
    IEntityWithChangeTracker, IEntityWithRelationships 
{ 
    ... 
} 

sadece IEntityWithRelationships.RelationshipManagerObjectContext yol açar: anlatıldığı geçici çözüm olarak tanımlanır varlık EntityObject elde edilir, çünkü tek seçenek gibi görünüyor. Bu, EF 4.

'da değişmemiştir. Ayrıca, içeriğe varlıktan erişmek yaygın değildir. Bunun, EF'in üzerine Aktif Kayıt Kalıbının uygulanması durumunda yardımcı olabileceğini hayal edebiliyorum, ancak bu durumda, muhtemelen, varlığın statik yönteminin içindeki bağlamı oluşturmayı da kontrol edebileceksiniz. varlık. Diğer durumlarda, olabildiğince kaçınmanız gereken bir şey olduğunu söyleyebilirim.

+0

Kesin yanıtınız için teşekkürler, Ladislav. İddialarına katılmamalıyım "mümkün olduğunca kaçınmanız gereken bir şeydir". Açıkçası, buna bir ihtiyaç var, ya da nasıl yapılacağına dair sorular ve yazılar asla yazılmayacaktı. Çoğu varlık örneği için ObjectContext'e başvuru yapmanın bir yolu var, ancak bu verimsiz.Nesnenin kendi bağlamından bağlamını almak, özellikle Entity Framework modelleri tarafından desteklenmeyen veri ile ilgili işlemleri gerektiren uzantı yöntemleri ile istenen birçok geçerli senaryo vardır. –

0

Bu benim kullandığım şeydir; Bir projeye eklemek basit, konvansiyonel bir yaklaşımdır.

İlk olarak, nesne bağlamı kancalar ekleyin:

public partial class Database1Entities 
{ 
    partial void OnContextCreated() 
    { 
     this.ObjectMaterialized += (_, e) => 
     { 
      try 
      { 
       dynamic entity = e.Entity; 
       entity.ObjectContext = this; 
      } 
      catch (RuntimeBinderException) 
      { 
      } 
     }; 
     this.ObjectStateManager.ObjectStateManagerChanged += (_, e) => 
     { 
      if (e.Action == CollectionChangeAction.Add) 
      { 
       try 
       { 
        dynamic entity = e.Element; 
        entity.ObjectContext = this; 
       } 
       catch (RuntimeBinderException) 
       { 
       } 
      } 
      else if (e.Action == CollectionChangeAction.Remove) 
      { 
       try 
       { 
        dynamic entity = e.Element; 
        entity.ObjectContext = null; 
       } 
       catch (RuntimeBinderException) 
       { 
       } 
      } 
     }; 
    } 
} 

Bu dinamik nesne bağlamında ilişkili olduğu tüm varlık üzerinde ObjectContext adlı bir özellik ayarlamak dener.

Sonraki, varlık türleri için ObjectContext ekleyin:

public partial class Table1 
{ 
    /// <summary> 
    /// Gets or sets the context for this entity. 
    /// This should not be set by end-user code; this property will be set 
    /// automatically as entities are created or added, 
    /// and will be set to <c>null</c> as entities are detached. 
    /// </summary> 
    public Database1Entities ObjectContext { get; set; } 
} 

Bu çözüm her varlık türüne eklenecek bir ObjectContext özelliğini gerektirir.

+0

Cevabınız için teşekkürler, Stephen. Ne yazık ki, bu özelliği her varlık türüne eklemek mümkün değildir veya sürdürülebilir değildir. –

+0

@John: Bu durumda, bağlantılı özellikleri kullanarak diğer yanıtıma bakın. –

3

connected properties kullanarak başka bir çözüm var. Bu (: denenmemiş kod uyarısı): gibi görünecektir bağlı özelliklerini kullanma

public partial class Database1Entities 
{ 
    private struct ObjectContextProperty { } 

    partial void OnContextCreated() 
    { 
     this.ObjectMaterialized += (_, e) => 
     { 
      e.Entity.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(this); 
     }; 
     this.ObjectStateManager.ObjectStateManagerChanged += (_, e) => 
     { 
      if (e.Action == CollectionChangeAction.Add) 
      { 
       e.Element.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(this); 
      } 
      else if (e.Action == CollectionChangeAction.Remove) 
      { 
       e.Element.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(null); 
      } 
     }; 
    } 

    /// <summary> 
    /// Gets the object context for the entity. Returns <c>null</c> if the entity is detached. 
    /// </summary> 
    /// <param name="entity">The entity for which to return the object context.</param> 
    public static Database1Entities FromEntity(EntityObject entity) 
    { 
     return entity.GetConnectedProperty<Database1Entities, ObjectContextProperty>().GetOrConnect(null); 
    } 
} 

Sonra bir varlık nesneden nesne bağlamı almak için Database1Entities.FromEntity kullanabilirsiniz. Ayrıca hem İstersen varlık nesneler üzerinde gerçek bir özellik tanımlayabilirsiniz:

public partial class Table1 
{ 
    /// <summary> 
    /// Gets the object context for this entity. Returns <c>null</c> if the entity is detached. 
    /// </summary> 
    public Database1Entities ObjectContext { get { return Database1Entities.FromEntity(this); } } 
} 

Bu çözümde, ObjectContext özelliği varlık isteğe bağlıdır nesneleri üzerinde.

+0

teşekkürler. Bağlantılı özelliklere biraz bakacağım ve bu projenin mantıklı olup olmadığını göreceğim. Bu soruyu cevaplamadaki zamanını takdir ediyorum. –

+0

İyi çalışma, Ayrıca tüm varlıklara GetObjectContext gibi bir yöntem eklemek için uzantı yöntemleri kullanabilirsiniz. public static Veritabanı1Yunıtlar GetObjectContext (bu EntityObject entityObject) { return Database1Entities.FromEntity (entityObject); } – MNZ

İlgili konular