Come ottenere il valore della chiave primaria con Entity Framework Core

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

Domanda

Attualmente utilizziamo il metodo seguente che dipende da IObjectContextAdapter in un repository astratto. Da quello che sto leggendo, sembra che qualsiasi cosa relativa a ObjectContext sia stata tagliata da Entity Framework Core. Il metodo seguente è l'unico posto in cui dipendiamo da qualsiasi cosa relativa a ObjectContext.

Vorremmo eseguire l'aggiornamento a Entity Framework Core. Questo è il nostro unico blocco stradale. C'è un modo per ottenere il valore della chiave primaria di un'entità con gli apis di 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);
}

Risposta accettata

Ho anche affrontato problemi simili e ho trovato la seguente soluzione

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

Risposta popolare

Sulla base della risposta di YuriyP è anche possibile ottenere informazioni chiave composte:

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

  }

Che potrebbe quindi essere utilizzato in modo simile:

var keyValues = context.FindPrimaryKeyValues(entity);    
var existingEntity = context.Set<TEntity>().Find(keyValues);



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché