2016-01-07 3 views
1

Pour une fonction de journalisation des modifications, j'ai besoin de récupérer la valeur de clé primaire de n'importe quelle entité. Cela sera écrit dans la table d'audit avec le nom de la table, les noms de propriété modifiés et les anciennes et nouvelles valeurs.Récupération des valeurs de clé d'une entité

Je pouvais refléter le type de l'entité particulière et rechercher une propriété [Key]. Cela fonctionnerait dans mon cas car j'utilise le code-first, les attributs et uniquement les clés à une seule colonne. Mais je ne suis pas sûr de la performance d'exécution de l'utilisation de la réflexion (non cachée).

Existe-t-il une méthode plus robuste et "officielle" pour obtenir la valeur de la clé primaire à partir d'une entité connue par EF?

Veuillez rester avec la dernière version EF (6.1.3). Je ne peux pas utiliser de solutions pour EF 4/5 qui accèdent aux fonctionnalités obsolètes ou supprimées.

Exemple de code

:

class MyEntity1 
{ 
    [Key] 
    public Guid KeyColumn { get; set; } 
    // ... 
} 

class MyEntity2 
{ 
    [Key] 
    public string EntityId { get; set; } 
    // ... 
} 

class MyContext : DbContext 
{ 
    public DbSet<MyEntity1> Entities1 { get; set; } 
    public DbSet<MyEntity2> Entities2 { get; set; } 

    public object GetEntityKey(object entity) 
    { 
     return ???(entity); 
     // Expected: The value of the property with [Key] 
    } 
} 

PS: J'utilise la solution de contournement suivante tout manuel, dans tout le monde de cas est à la recherche de la même solution. Mais ce n'est pas simple à maintenir lorsque de nouvelles entités sont ajoutées.

public object GetEntityKey<T>(T entity) 
{ 
    if (typeof(T) == typeof(MyEntity1)) 
    { 
     return ((MyEntity1)(object)entity).KeyColumn; 
    } 
    if (typeof(T) == typeof(MyEntity2)) 
    { 
     return ((MyEntity2)(object)entity).EntityId; 
    } 
    // Important: Makes you aware of new entities 
    throw new NotSupportedException("The specified entity type is not supported."); 
} 

Répondre

2

Je ne peux pas commenter sur la performance de l'utilisation de la réflexion pour cela, mais vous pouvez certainement trouver le PK d'une entité donnée en utilisant la réflexion et la recherche de l'attribut [Key] (Je suppose qu'ils ont tous cet attribut):

public object GetEntityKey<T>(T entity) 
{ 
    return typeof(T).GetProperties().Where(x => Attribute.IsDefined(x, typeof(KeyAttribute))).Single().GetValue(entity); 
} 
+1

Cela ne devrait-il pas être 'typeof (KeyAttribute)'? –

+0

Bon endroit, mis à jour la réponse. – James