Trabajar con claves de entidad (Entity Framework)

Cada tipo de entidad tiene una clave que está basada en una o más propiedades escalares de la entidad. El elemento Key define las claves en el modelo conceptual. Al igual que en las bases de datos relacionales, estos valores de clave se utilizan para comprobar la unicidad de una entidad determinada y para mejorar el rendimiento de las consultas. Normalmente, las propiedades de clave están asignadas a una columna de clave en la tabla subyacente, bien a una columna de identidad o a alguna otra columna restringida de modo que garantice un valor único. Para obtener más información sobre cómo se definen las claves en el modelo conceptual, vea Key (Elemento) (CSDL).

Cuando una consulta de objeto devuelve un objeto, Entity Framework materializa el objeto entidad. También materializa la clave de entidad en una instancia de la clase EntityKey. Puede obtener acceso a esta EntityKey desde la propiedad EntityKey de un objeto que implementa IEntityWithKey. EntityObject, que es la clase base para todas las clases de datos generadas por las herramientas de Entity Data Model , también implementa IEntityWithKey.

Dd283139.note(es-es,VS.100).gifNota:
Entity Framework no requiere que implemente IEntityWithKey en una clase de datos personalizada.

Construir y utilizar un objeto EntityKey

Un objeto EntityKey se compone de propiedades EntitySetName y EntityContainerName y de una matriz de uno o más pares clave-valor. Un par clave-valor está compuesto de un nombre de propiedad y un valor de propiedad. Los pares clave-valor se incluyen como uno o más objetos EntityKeyMember en la propiedad EntityKeyValues.

Dd283139.note(es-es,VS.100).gifNota:
Al utilizar uno de los constructores de EntityKey, el valor de cadena proporcionado al parámetro qualifiedEntitySetName es el EntitySetName precedido por el EntityContainerName, como en "NombreContenedorEntidades.NombreConjuntoEntidades".

También puede utilizar el método CreateEntityKey sobre ObjectContext para obtener la EntityKey para un objeto desasociado. Si el objeto no tiene una clave válida, el contexto construye una nueva instancia de EntityKey para el objeto especificado. Para obtener más información, vea Cómo: Crear un EntityKey (Entity Framework).

Dado que una clave de entidad identifica de forma única a una entidad, se puede crear una entidad con solo la clave, y asociar el objeto a un contexto, incluso si los valores de objeto restantes no se recuperaron del origen de datos. Para obtener más información, vea Cómo asociar objetos relacionados (Entity Framework). Una clave de entidad también se puede utilizar para recuperar un objeto del contexto o del origen de datos. Para obtener más información, vea Cómo: Devolver un objeto concreto usando su clave (Entity Framework).

Claves de entidad de longitud fija

Entity Framework resuelve las identidades mediante el valor de la EntityKey, que corresponde a una clave principal de la base de datos. Si una consulta devuelve un objeto con una EntityKey que ya existe en ObjectContext, no se crea un nuevo objeto. Si está trabajando con columnas de tamaño fijo en la base de datos y está conservando valores más cortos que el tamaño especificado en la base de datos, algunas bases de datos rellenarán los tipos de tamaño fijo con espacios o ceros. SQL Server rellena los tipos de cadena de tamaño fijo con espacios finales. Cuando los tipos de tamaño fijo (como binario o char) se utilizan como claves principales, podrían producirse problemas de resolución de identidad.

Considere el ejemplo siguiente. La tabla Product tiene una columna de longitud fija de tamaño 10 para la clave principal. Se crea un objeto Product con EntityKey AB100 y se agrega a ObjectContext. Cuando el objeto se guarda en la base de datos, la clave se rellena con espacios finales porque la columna es de un tamaño fijo y el valor guardado es más corto que el tamaño especificado en la base de datos. Una consulta subsiguiente para un objeto con una EntityKey de AB100 devolverá un objeto con una EntityKey diferente (AB100 seguida de espacios finales), ya que SQL Server compara AB100 con la cadena rellena de espacios. Entity Framework no recorta o rellena los valores de propiedades. El resultado es que un nuevo objeto (con EntityKeyAB100 seguida de espacios finales) se agrega al ObjectContext.

Product p1= new Product 
{ 
    ProductID = "AB100", 
    Description = "New product" 
}; 
// An object with EntityKey "AB100" is added to ObjectContext.  ctx.Products.AddObject(p1); 
// The object is saved in the database with a primary key of 
// "AB100     " because the column is of a fixed size.  ctx.SaveChanges();
// When a query is executed for an object with key "AB100", SQL Server // matches the key to "AB100     ".  The result is that a new object 
// with EntityKey "AB100     " is added to ObjectContext.  Product p2 = ctx.Products.First(p => p.ProductCode == "AB100");  

Para evitar este comportamiento indeseable, puede realizar una de las siguientes acciones:

  • Utilice un tipo de longitud variable en lugar de uno de longitud fija en la base de datos.

  • Rellene el valor de EntityKey con espacios finales o ceros en el cliente. Puede utilizar el método PadRight para rellenar una cadena con espacios.

Claves de entidad y objetos agregados

Cuando se crea una nueva entidad, Entity Framework define la clave temporal y establece la propiedad IsTemporary en true. Al llamar al método SaveChanges, Entity Framework asigna una clave permanente y establece la propiedad IsTemporary en false.

Si el valor de la columna correspondiente es una identidad que se genera en la base de datos, establezca el atributo StoreGeneratedPattern del elemento Property de una entidad del modelo de almacenamiento en Identity. Cuando las herramientas de Entity Data Model generan un modelo de datos desde un origen de datos existente, el atributo StoreGeneratedPattern se agrega a cada elemento Property (Elemento) (CSDL) que representa una identidad o a una columna calculada en el origen de datos. Entity Framework reemplaza el valor de la propiedad en una clave temporal con el valor de identidad generado por el origen de datos una vez llamado SaveChanges.

A continuación se detalla el proceso interno que reemplaza la clave temporal por una clave permanente que contiene los valores generados por el servidor:

  1. Se construye el objeto entidad.

    En este punto, todas las propiedades de clave tienen valores predeterminados, ya sean null o 0.

  2. El nuevo objeto se agrega al ObjectContext llamando al método AddObject sobre ObjectContext o ObjectSet o añadiendo un objeto a la colección de objetos sobre el extremo "varios" de la relación.

    En este punto, Entity Framework genera una clave temporal, que se utiliza para almacenar los objetos en el ObjectStateManager.

  3. Se llama al método SaveChanges sobre el ObjectContext.

    Entity Framework genera una instrucción INSERT que se ejecuta sobre el origen de datos.

  4. Si la operación INSERT se ejecuta correctamente, los valores generados por el servidor se vuelven a escribir en el ObjectStateEntry.

  5. ObjectStateEntry actualiza el objeto con el valor generado por el servidor.

  6. Cuando se llama al método AcceptChanges sobre el ObjectStateEntry, se calcula una EntityKey permanente utilizando los nuevos valores generados por el servidor.

    Dd283139.note(es-es,VS.100).gifNota:
    Se llama automáticamente a AcceptChanges al final de la ejecución de SaveChanges, o cuando se llama al método SaveChanges con la marca AcceptAllChangesAfterSave.

  7. El ObjectStateManager reemplaza todas las instancias de la clave temporal por la nueva clave permanente.

Valores de propiedad GUID

Entity Framework admite propiedades de entidad que devuelven un tipo Guid para garantizar la unicidad.

Entity Framework es compatible con los valores de identidad de tipo GUID generados por el servidor, pero el proveedor debe ser capaz de devolver el valor de identidad generado por el servidor después de la inserción de una fila. SQL Server puede devolver el tipo GUID generado por el servidor a través de la cláusula OUTPUT a partir de SQL Server 2005. Si un proveedor no admite el equivalente de la cláusula OUTPUT, genere los valores GUID para los nuevos objetos en el cliente. Para ello, recomendamos controlar el evento SavingChanges para generar un nuevo valor GUID para cualquier objeto entidad en el estado Added. Para obtener más información, vea Cómo: Ejecutar la lógica de negocios al guardar los cambios (Entity Framework).

Al generar o actualizar un modelo de datos con el Entity Data Model Wizard o Update Model Wizard, se generan automáticamente propiedades GUID de tipos de entidad para las columnas de tipo uniqueidentifier en el origen de datos. Un origen de datos también puede utilizar columnas binarias de 16 bytes para almacenar los valores GUID. Dado que las herramientas generan una propiedad binaria para cada columna binaria del origen de datos, debe actualizar manualmente la asignación de dichas columnas a las propiedades GUID editando el archivo .edmx. Para obtener más información, vea How to: Map a GUID Property to a Binary Column.

En esta sección

Cómo: Crear un EntityKey (Entity Framework)

Vea también

Tareas

Cómo: Crear un EntityKey (Entity Framework)

Otros recursos

Entity Data Model Tools