i setup Audit.net for my model and all works fine but nested properties are ignored and got 0 in corresponding log table fields
model
public class ElementoWorkflow : BaseObject<ElementoWorkflow, int>
{
public override int Id { get; set; }
public required Stato StatoOrigine { get; set; }
public required bool Finale { get; set; } = false;
}
public class Stato : ServiceRegistryObject
{
public override RegistryType Gruppo {
get => RegistryType.Stato;
set => throw new InvalidOperationException("Non è possibile modificare il Gruppo di appartenenza. Utilizzare la classe generica ServiceRegistryObject.");
}
}
public class ServiceRegistryObject : ServiceBaseObject<ServiceRegistryObject, int>
{
public override int Id { get; set; }
public virtual string? Codice { get; set; }
public virtual RegistryType Gruppo { get; set; }
}
public abstract class ServiceBaseObject<TEntity, TKey> : BaseObject<TEntity, TKey>
where TEntity : class
{
public abstract bool Annullato { get; set; }
public abstract TKey Ordine { get; set; }
}
public void Configure(EntityTypeBuilder<ElementoWorkflow> builder)
{
builder
.ToTable($"NAT_DASH_ELEMENTO_WORKFLOW_007")
.HasKey(c => c.Id)
.HasName("NAK_DASH_007");
builder.Property(b => b.Id)
.HasColumnName("ID_007");
builder.Property<int>("IdStatoOrigine")
.HasColumnName("ID_STATO_ORIGINE_007")
.IsRequired();
builder.HasOne(c => c.StatoOrigine)
.WithMany()
.HasForeignKey("IdStatoOrigine")
.HasPrincipalKey(g => g.Id)
.IsRequired();
builder.Property(b => b.Finale)
.HasColumnName("FINALE_007")
.IsRequired();
}
below my config
public DatabaseContext(DbContextOptions<DatabaseContext> options, ILoggerFactory loggerFactory, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_loggerFactory = loggerFactory;
//this.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
this.ChangeTracker.LazyLoadingEnabled = false;
Audit.EntityFramework.Configuration.Setup()
.ForContext<DatabaseContext>(config => config
.IncludeEntityObjects()
.ReloadDatabaseValues(true)
.AuditEventType("DatabaseContext"))
.UseOptOut()
.IgnoreAny(t => t.Name.EndsWith("History"));
Audit.Core.Configuration.Setup()
.UseEntityFramework(ef => ef
.AuditTypeExplicitMapper(m => m
.Map<ElementoWorkflow, ElementoWorkflowAudit>()
.AuditEntityAction<IAudit>((evt, entry, auditEntity) =>
{
auditEntity.AuditData = DateTime.UtcNow;
auditEntity.AuditUser = httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(c => c.Type.Contains(TipoClaim.matricola.ToString()))?.Value;
auditEntity.AuditAction = entry.Action;
})
)
);
and audit objects
internal class ElementoWorkflowAudit : IAudit
{
public int AuditId { get; set; }
public string AuditAction { get; set; }
public string? AuditUser { get; set; }
public DateTime AuditData { get; set; }
public int Id { get; set; }
public Stato StatoOrigine { get; set; }
public bool Finale { get; set; } = false;
}
public void Configure(EntityTypeBuilder<ElementoWorkflowAudit> builder)
{
builder
.ToTable("NAT_DASH_AUD_ELEMENTO_WORKFLOW_007")
.HasKey(e => e.AuditId)
.HasName("NAK_DASH_AUD_ELEMENTO_WORKFLOW_007");
builder.Property(b => b.AuditId).HasColumnName("AuditId")
.HasDefaultValueSql($"SYUNA{Costanti.CodiceApplicazione}.SEQ_{Costanti.CodiceApplicazione}__AUD.NEXTVAL");
builder.Property(b => b.AuditData);
builder.Property(b => b.AuditAction);
builder.Property(b => b.AuditUser);
builder.Property(b => b.Id)
.HasColumnName("ID_007");
builder.Property<int>("IdStatoOrigine")
.HasColumnName("ID_STATO_ORIGINE_007");
builder.HasOne(c => c.StatoOrigine)
.WithMany()
.HasForeignKey("IdStatoOrigine")
.HasPrincipalKey(g => g.Id);
builder.Property(b => b.Finale)
.HasColumnName("FINALE_007");
}
and oracle db table
CREATE TABLE NAT_DASH_AUD_ELEMENTO_WORKFLOW_007
(
"AuditId" NUMBER(9, 0) DEFAULT "SYUNADASH"."SEQ_DASH__AUD"."NEXTVAL" NOT NULL
, "AuditAction" VARCHAR2(250 BYTE)
, "AuditUser" VARCHAR2(250 BYTE)
, "AuditData" DATE
, ID_007 NUMBER(12, 0)
, ID_STATO_ORIGINE_007 NUMBER(9, 0)
, FINALE_007 NUMBER(1, 0)
, CONSTRAINT NAK_DASH_AUD_ELEMENTO_WORKFLOW_007 PRIMARY KEY
(
"AuditId"
)
)
where ID_STATO_ORIGINE_007 is always null
The navigation properties are not included as changes for the parent entity unless they are owned entities.
So, EF will detect and include the change in the foreign key properties, and when the child entity is modified, it will include the change for that entity type.
You could share a working sample that reproduces the issue and open an issue here for better support.