Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set base properties (DateModified, ModifiedBy) on BulkInsertOrUpdate #932

Closed
Tyler-V opened this issue Aug 25, 2022 · 1 comment
Closed
Labels

Comments

@Tyler-V
Copy link

Tyler-V commented Aug 25, 2022

Hello,

We have entities that inherit BaseEntity

public abstract class BaseEntity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    [Column(Order = 0)]
    public int Id { get; set; }

    public string CreatedBy { get; set; } = "SYSTEM";

    public string UpdatedBy { get; set; } = "SYSTEM";

    public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;

    public DateTimeOffset DateModified { get; set; } = DateTimeOffset.UtcNow;
}

On insert or update, we would like to set these properties before saving when using the Bulk library

For regular Entity Framework we are using the common approach of overriding SaveChanges and checking the ChangeTracker which works great

i.e.

    public override async Task<int> SaveChangesAsync(
        CancellationToken cancellationToken = default)
    {
        var time = DateTimeOffset.UtcNow;

        foreach (var entityEntry in ChangeTracker
                     .Entries()
                     .Where(e => e.Entity is BaseEntity &&
                                 e.State is EntityState.Added or EntityState.Modified))
        {
            var entity = (BaseEntity)entityEntry.Entity;

            entity.UpdatedBy = "SYSTEM";
            entity.DateModified = time;

            if (entityEntry.State != EntityState.Added)
            {
                continue;
            }

            entity.CreatedBy = "SYSTEM";
            entity.DateCreated = time;
        }

        return await base.SaveChangesAsync(cancellationToken);
    }

Few options come to mind, we can track these entities and implement an inner class for BulkSaveChangesAsync which may be the only way to solve this

    public async Task BulkSaveChangesAsync(BulkConfig bulkConfig = null, Action<decimal> progress = null,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        foreach (var entityEntry in _context.ChangeTracker.Entries()
                     .Where(e => e.Entity is BaseEntity && e.State is EntityState.Added or EntityState.Modified))
        {
            var baseEntity = (BaseEntity)entityEntry.Entity;
            baseEntity.UpdatedBy = "SYSTEM";

            if (entityEntry.State != EntityState.Added)
            {
                continue;
            }

            baseEntity.CreatedBy = "SYSTEM";
        }

        await _context.BulkSaveChangesAsync(bulkConfig, progress, cancellationToken);
    }

We are currently using more calls from BulkInsertOrUpdateAsync, we could manually update these properties but I want to use something more concrete and this becomes a nightmare for parent -> child -> subchild that all inherit BaseEntity individually and have their own DateCreated / DateModified

Just wondering what the best recommended approach is for managing properties like this

@borisdj
Copy link
Owner

borisdj commented Dec 8, 2022

Zou could try to override extension methods.
That approach is explained here: #56

@borisdj borisdj closed this as completed Dec 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants