Cómo obtener el valor de la clave principal con Entity Framework Core

entity-framework entity-framework-core primary-key repository-pattern

Pregunta

Actualmente estamos utilizando el siguiente método que depende de IObjectContextAdapter en un Repositorio abstracto. Por lo que estoy leyendo, parece que todo lo relacionado con ObjectContext está siendo eliminado de Entity Framework Core. El método a continuación es el único lugar en el que dependemos de cualquier cosa relacionada con ObjectContext.

Nos gustaría actualizar a Entity Framework Core. Este es nuestro único bloqueo de carretera. ¿Hay alguna manera de obtener el valor de la clave principal de una entidad con las apis de Entity Framework Core?

// Entity Framework
public virtual int GetKey(T entity)
{
    var oContext = ((IObjectContextAdapter)_DbContext).ObjectContext;
    var oSet = oContext.CreateObjectSet<T>();
    var keyName = oSet.EntitySet.ElementType
                                .KeyMembers
                                .Select(k => k.Name)
                                .Single();

    return (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
}

Respuesta aceptada

También me enfrenté con un problema similar y encontré la siguiente solución

// Entity Framework Core
public virtual int GetKey<T>(T entity)
{
    var keyName = Context.Model.FindEntityType(typeof (T)).FindPrimaryKey().Properties
        .Select(x => x.Name).Single();

    return (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
}

Respuesta popular

De acuerdo con la respuesta de YuriyP, también podría obtener información clave compuesta:

 public static class Extensions {

    public static IEnumerable<string> FindPrimaryKeyNames<T>(this DbContext dbContext, T entity) {
      return from p in dbContext.FindPrimaryKeyProperties(entity) 
             select p.Name;
    }

    public static IEnumerable<object> FindPrimaryKeyValues<T>(this DbContext dbContext, T entity) {
      return from p in dbContext.FindPrimaryKeyProperties(entity) 
             select entity.GetPropertyValue(p.Name);
    }

    static IReadOnlyList<IProperty> FindPrimaryKeyProperties<T>(this DbContext dbContext, T entity) {
      return dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties;
    }

    static object GetPropertyValue<T>(this T entity, string name) {
      return entity.GetType().GetProperty(name).GetValue(entity, null);
    }

  }

Que luego podría ser utilizado en como tal:

 public static class Extensions {

    public static IEnumerable<string> FindPrimaryKeyNames<T>(this DbContext dbContext, T entity) {
      return from p in dbContext.FindPrimaryKeyProperties(entity) 
             select p.Name;
    }

    public static IEnumerable<object> FindPrimaryKeyValues<T>(this DbContext dbContext, T entity) {
      return from p in dbContext.FindPrimaryKeyProperties(entity) 
             select entity.GetPropertyValue(p.Name);
    }

    static IReadOnlyList<IProperty> FindPrimaryKeyProperties<T>(this DbContext dbContext, T entity) {
      return dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties;
    }

    static object GetPropertyValue<T>(this T entity, string name) {
      return entity.GetType().GetProperty(name).GetValue(entity, null);
    }

  }



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué