2017-04-13 19 views
0

我想在模型中獲得主鍵名稱,但我的數據庫是在Fluent Api中設計的,我發現的所有示例都是在DataAnnotation中設計的。C# - 審計日誌 - 如何從Fluent Api中設計的模型中獲取PK名稱?

我重寫了DbContext的SaveChanges()以創建一個審計日誌。

這是保存審計日誌的代碼。

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

查看ID_Registro屬性,它接收操作的ID。 在這一行中,keyName需要指定主鍵字段的名稱。 並且該行將導致保存的ID。 但是由於沒有找到主鍵,因此此字段發生錯誤。

我該如何解決這個問題?

編輯:

這是模型。 Codigo是主鍵。

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

這是映射:

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

注意HasKey決定Codigo作爲主鍵並沒有在模型中沒有DataAnnotation。

回答

0

這似乎爲我工作:

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

此拋出NullReferenceException異常。 EntityKeyValues爲null。我添加了我的模型和映射到描述,也許它有幫助。 –