Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EntityFramework OwnedType with Soft-delete

I have an issue with Owned Types on my entites, because I added an override for SaveChanges to make soft-deletes possible. Basically I override the state of the Entity to modified instead of delete in the SaveChanges and add some meta information to the entity. This works well unless I add a OwnedType onto the entity.

When I do this, EF tries to set all values from the OwnedType to NULL, which is not possible in my example because the Strings are not nullable.

I am not exactly sure how I can fix this behaviour, because I need to set the DeleteBehaviour to NoAction, but I couldn't find a way to do this at the moment. Can anyone explain to me how I can solve this issue?

MainEntity.cs

public class MainEntity: SoftDeleteEntityBase
{
    public int Id { get; set; }
    public LocalizedStringSet MultilangTitle { get; set; } = new LocalizedStringSet();
}

LocalizedStringSet.cs

public class LocalizedStringSet
{
    [MaxLength(4000)]
    public string En { get; set; } = string.Empty;

    [MaxLength(4000)]
    public string Fr { get; set; } = string.Empty;
}

MainEntityConfiguration.cs

public class MainEntityConfiguration : IEntityTypeConfiguration<MainEntity>
{
    public void Configure(EntityTypeBuilder<MainEntity> builder)
    {
        if (builder is null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.HasKey(x => x.Id);
        builder.Property(x => x.Id).ValueGeneratedOnAdd();
        builder.OwnsOne(o => o.MultilangTitle);
    }
}

ApplicationDbContext.cs

public override int SaveChanges()
{
    if (entry.Entity is ISoftDeleteEntityBase managedCreationSoftDelete)
        {
            switch (entry.State)
            {
                case EntityState.Deleted:
                {
                        entry.State = EntityState.Modified;
                        managedCreationSoftDelete.DeletedBy = creator;
                        managedCreationSoftDelete.Deleted = DateTime.Now;
                        break;
                }

            }
        }
    return base.SaveChanges();
}
like image 578
nino Avatar asked Oct 20 '25 15:10

nino


1 Answers

I found a way to solve it, but I am not sure if there is a better way to do this.

public override int SaveChanges()
{
    if (entry.Entity is ISoftDeleteEntityBase managedCreationSoftDelete)
        {
            switch (entry.State)
            {
                case EntityState.Deleted:
                {
                        entry.State = EntityState.Modified;
                        managedCreationSoftDelete.DeletedBy = creator;
                        managedCreationSoftDelete.Deleted = DateTime.Now;
                        
                        foreach (var reference in entry.References)
                        {
                            if (reference.TargetEntry?.Entity.GetType() == typeof(LocalizedStringSet))
                            {
                                if (reference.TargetEntry != null)
                                {
                                    reference.TargetEntry.State = EntityState.Unchanged;
                                }
                            }
                        }

                        break;
                }

            }
        }
    return base.SaveChanges();
}


like image 190
nino Avatar answered Oct 23 '25 07:10

nino