Closed kensleebos closed 1 year ago
Can you create and share a minimal-reproducible-example ?
Since I don't know what the _repository.ById
, _mapper
, and _reposutory.Update
do, it's impossible to say what could be wrong.
Can you try enabling logging for SQL statements in your DbContext so that you can check if any delete is happening?
I use a generic repository that does the following:
public T? ById(object id, Func<IQueryable<T?>, IIncludableQueryable<T, object>>? includes = null)
{
var type = Context.Model.FindEntityType(typeof(T));
var primaryKey = type?.FindPrimaryKey();
if (primaryKey == null)
{
throw new ArgumentException("Entity does not have any primary key defined.");
}
var properties = primaryKey.Properties;
var primaryKeyName = properties.Select(p => p.Name).FirstOrDefault();
var primaryKeyType = properties.Select(p => p.ClrType).FirstOrDefault();
object? primaryKeyValue = null;
try
{
if (primaryKeyType != null)
{
primaryKeyValue = Convert.ChangeType(id, primaryKeyType, CultureInfo.InvariantCulture);
}
}
catch (Exception)
{
throw new ArgumentException(
$"You can not assign a value of type {id.GetType()} to a property of type {primaryKeyType}");
}
var pe = Expression.Parameter(typeof(T), "entity");
if (primaryKeyName == null)
{
return null;
}
var me = Expression.Property(pe, primaryKeyName);
if (primaryKeyType == null)
{
return null;
}
var constant = Expression.Constant(primaryKeyValue, primaryKeyType);
var body = Expression.Equal(me, constant);
var expressionTree = Expression.Lambda<Func<T, bool>>(body, pe);
IQueryable<T?> query = Context.Set<T>();
includes?.Invoke(query).Load();
return query.FirstOrDefault(expressionTree!);
}
public void Update(T entityToUpdate)
{
DbSet.Update(entityToUpdate);
Context.Entry(entityToUpdate).State = EntityState.Modified;
}
The mapper is just automapper : https://automapper.org/
CreateMap<RandomDataList, RandomDataListDto>().ReverseMap();
CreateMap<RandomDataListItem, RandomDataListItemDto>().ReverseMap();
The DTO models are exactly the same as the entity models
My database config:
services.AddDbContext<InstanceCreatorContext>(
o =>
{
o.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
o.EnableDetailedErrors();
o.AddInterceptors(new AuditSaveChangesInterceptor());
o.EnableSensitiveDataLogging();
o.UseLazyLoadingProxies(false);
});
I checked the queries output and there is no delete statement
i found the problem, its entity framework that doesn't like it when you update the children trough the parent.
Describe the bug I have a object with child objects, the parent is being updated. When this occurs there are multiple audit entries created with Updates and Deletes. No child is actualy being deleted.
So when a child is updated the following audits are being inserted. In this example no child delete action is invoked. Initial:
Update request:
New Audit Record: Update Parent Update Child 1 Update Child 2 Delete Child 1 Delete Child 2
This doesnt make sense.
My Classes:
My Config:
To Reproduce Update/Insert/Delete any item in the list, but update the parent object with the list, aka:
Expected behavior I dont want so many audit entries, its not logical, i only want the main object update audit or the specific child object audit. Also it doesnt make sense that it creates Delete Audits
Libraries :
Target .NET framework:
.NET 6
Additional Info When i include the entity objects in the Json what stands out is that the Item update json includes its parent, which has a list of items, the item being updated here is null but the sibling isn't maybe this causes for multiple audits.