2017-04-13 4 views
0

J'essaie d'obtenir le nom de clé primaire dans un modèle, mais ma base de données est conçue dans Fluent API et tous les exemples que j'ai trouvés sont conçus dans DataAnnotation.C# - Audit Log - Comment obtenir le nom PK du modèle conçu dans Fluent Api?

Je surcharge SaveChanges() de DbContext pour créer un journal d'audit.

C'est le code pour enregistrer le journal d'audit.

private List<AuditLogModel> GetAuditRecordsForChange(DbEntityEntry dbEntry, int? id_usuario = null) 
    { 
     List<AuditLogModel> result = new List<AuditLogModel>(); 

     DateTime changeTime = DateTime.Now; 

     // Get the Table() attribute, if one exists 
     TableAttribute tableAttr = dbEntry.Entity.GetType().GetCustomAttributes(typeof(TableAttribute), false).SingleOrDefault() as TableAttribute; 

     // Get table name (if it has a Table attribute, use that, otherwise get the pluralized name) 
     string tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name; 

     // Get primary key value (If you have more than one key column, this will need to be adjusted) 
     //string keyName = dbEntry.Entity.GetType().GetProperties().Single(p => p.GetCustomAttributes(typeof(KeyAttribute), false).Count() > 0).Name; 
     var oc = ((IObjectContextAdapter)this).ObjectContext; 
     EntityKey key = oc.ObjectStateManager.GetObjectStateEntry(dbEntry.Entity).EntityKey; 
     string keyName = key.EntitySetName; 

     if (dbEntry.State == EntityState.Added) 
     { 
      // For Inserts, just add the whole record 
      // If the entity implements IDescribableEntity, use the description from Describe(), otherwise use ToString() 
      result.Add(new AuditLogModel() 
      { 
       Id_Usuario = id_usuario, 
       Id_Registro = (int)dbEntry.CurrentValues.GetValue<object>(keyName), // Again, adjust this if you have a multi-column key 
       EventoTipo = "I", // INSERT 
       Tabela = tableName, 
       NovoValor = dbEntry.CurrentValues.ToObject().ToString() 
      }); 
      //NovoValor = (dbEntry.CurrentValues.ToObject() is IDescribableEntity) ? (dbEntry.CurrentValues.ToObject() as IDescribableEntity).Describe() : dbEntry.CurrentValues.ToObject().ToString() 
     } 

     // Otherwise, don't do anything, we don't care about Unchanged or Detached entities 

     return result; 
    } 

Regardez la propriété ID_Registro, celle-ci reçoit l'ID de l'opération. Dans cette ligne, keyName doit spécifier le nom du champ de clé primaire. Et la ligne se traduira par un ID qui est enregistré. Mais ce champ donne une erreur parce que la clé primaire est introuvable.

Comment puis-je résoudre ce problème?

EDIT:

C'est le modèle. Codigo est la clé primaire.

public sealed class AcessoLogModel 
{ 
    public int Codigo { get; set; } 
    public int CodigoUsuario { get; set; } 
    public UsuarioModel Usuario { get; set; } 
    public string IP { get; set; } 
    public DateTime Horario { get; set; } 
} 

c'est la mise en correspondance:

public AcessoLogMapping() 
    { 
     ToTable("TB_ACESSO_LOG"); 
     HasKey(x => x.Codigo); 

     Property(x => x.Codigo).HasColumnName("ID_ACESSO_LOG") 
      .HasColumnType("INT") 
      .IsRequired(); 

     Property(x => x.CodigoUsuario).HasColumnName("ID_USUARIO_ACESSO_LOG") 
      .HasColumnType("INT") 
      .IsRequired(); 

     HasRequired(x => x.Usuario) 
      .WithMany() 
      .HasForeignKey(x => x.CodigoUsuario) 
      .WillCascadeOnDelete(false); 

     Property(x => x.Horario).HasColumnName("HORARIO_ACESSO_LOG") 
      .HasColumnType("DATETIME") 
      .IsRequired(); 

     Property(x => x.IP).HasColumnName("IP_ACESSO_LOG") 
      .HasColumnType("VARCHAR") 
      .HasMaxLength(180) 
      .IsRequired(); 
    } 

Notez que Haskey détermine Codigo comme la clé primaire et il n'y a pas DataAnnotation dans le modèle.

Répondre

0

Cela semble fonctionner pour moi:

Id_Registro = entry.State == EntityState.Added ? null : ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity).EntityKey.EntityKeyValues[0].Value.ToString() 
+0

Ce lancer une NullReferenceException. EntityKeyValues ​​est null. J'ai ajouté mon modèle et mappage à la description, peut-être que ça aide. –