2011-04-18 24 views
5

Estoy creando extensiones para mis objetos EntityFramework como se describe en How to: Customize Generated Data Objects, pero en algunas de esas extensiones necesito obtener el ObjectContext de la instancia para buscar algunos otros valores en el modelo. He encontrado Tip 24 – How to get the ObjectContext from an Entity, pero eso fue escrito hace un par de años, que se hace referencia en este similar SO question, pero realmente espero que haya una mejor respuesta ahora.¿Cuál es la forma más rápida de obtener una referencia ObjectContext de un objeto entidad?

Seguramente esto debe ser algo que se necesita con la frecuencia suficiente para que la recuperación del contexto de objetos de una Entidad de la entidad en sí misma sea compatible con un método oficial.

Gracias de antemano por cualquier información más reciente sobre esta implementación.

Respuesta

0

No, no existe ningún método. La solución descrita se ve como la única opción, porque la entidad se deriva de EntityObject que se define como:

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

Como sé que sólo conduce a IEntityWithRelationships.RelationshipManagerObjectContext. Esto no se modificó en EF 4.

Además, no es muy común acceder al contexto de la entidad. Me imagino que esto puede ser útil en caso de implementar Patrón de registro activo sobre EF, pero en ese caso probablemente también tendría control sobre la creación del contexto dentro del método estático de la entidad, por lo que debería poder establecerlo en el entidad. En otros casos, diría que es algo que debes evitar tanto como sea posible.

+0

Gracias por su respuesta definitiva, Ladislav. Debo estar en desacuerdo con su afirmación "es algo que debe evitar tanto como sea posible". Claramente, hay una necesidad de esto, o las preguntas y publicaciones sobre cómo hacerlo nunca se hubieran escrito. Hay una forma de obtener una referencia al ObjectContext para la mayoría de instancias de entidades, pero es ineficiente.Hay muchos escenarios válidos donde se desea recuperar el contexto de un objeto desde el objeto en sí, en particular con métodos de extensión que requieren operaciones relacionadas con datos que actualmente no son compatibles con los modelos de Entity Framework. –

0

Esto es lo que uso; es un enfoque basado en convenciones que es simple de agregar a un proyecto.

En primer lugar, añadir ganchos a su contexto de objeto:

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) 
       { 
       } 
      } 
     }; 
    } 
} 

Este intentará establecer dinámicamente una propiedad llamada ObjectContext en cualquier entidad que se asocia con el contexto del objeto.

A continuación, añadir una ObjectContext a los tipos de entidades:

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; } 
} 

Esta solución no requiere una propiedad ObjectContext que se añade a cada tipo de entidad.

+0

Gracias por la respuesta, Stephen. Desafortunadamente, agregar esta propiedad a cada tipo de entidad simplemente no es factible o sostenible. –

+0

@John: en ese caso, vea mi otra respuesta usando propiedades conectadas. –

3

Hay otra solución, usando connected properties.

Utilización de las propiedades conectadas sería el siguiente (advertencia: código no probado):

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); 
    } 
} 

continuación, puede utilizar Database1Entities.FromEntity para obtener el contexto de objeto de un objeto entidad. También puede definir una propiedad real de los objetos de entidad, así que si quieres:

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); } } 
} 

En esta solución, la propiedad ObjectContext en la entidad de objetos es opcional.

+0

gracias. Investigaré un poco las propiedades conectadas y veré si eso tiene sentido para este proyecto. Agradezco tu tiempo al responder esta pregunta. –

+0

Buen trabajo. También puede usar métodos de extensión para agregar un método como GetObjectContext a todos los entityObjects. public static Database1Entities GetObjectContext (este entityObject entityObject) { return Database1Entities.FromEntity (entityObject); } – MNZ

Cuestiones relacionadas