I have a particular service operation that needs to update an entity but NOT update the LastModificationTime & User fields.
Any ideas on how this might be best achieved?
I had considered possibly overriding the "SetModificationAuditProperties" in my DB Context and detecting the context of the operation (presumably via the current Unit Of Work somehow). My operation would then need to explicity use a different unit of work manager. Would that be possible? If so, how do I replace the Current UoW?
9 Answer(s)
-
0
To answer my own question... I just spotted the UnitOfWorkManager.Begin() overload that allows us to pass in a UnitOfWorkOptions instance which could then be extended with my own properties...
However, it's important to note that the operation must mark itself with the [UnitOfWork] attribute set to IsDisabled = true.
public class ExtendedUnitOfWorkOptions : UnitOfWorkOptions { public ExtendedUnitOfWorkOptions() { UpdateLastModified = true; } public bool UpdateLastModified { get; set; } }
Then in my DbContext I can override SetModificationAuditProperties() function:
protected override void SetModificationAuditProperties(DbEntityEntry entry, long? userId) { var isEnabled = true; if (CurrentUnitOfWorkProvider != null && CurrentUnitOfWorkProvider.Current != null) { var uow = CurrentUnitOfWorkProvider.Current; if (uow.Options is ExtendedUnitOfWorkOptions) { isEnabled = (uow.Options as ExtendedUnitOfWorkOptions).UpdateLastModified; } } if (isEnabled) { base.SetModificationAuditProperties(entry, userId); } }
Which can be consumed within my special operation like:
[UnitOfWork(IsDisabled = true)] public virtual async Task SignOffIncident(IdInput input) { using (var unitOfWork = UnitOfWorkManager.Begin(new ExtendedUnitOfWorkOptions() { UpdateLastModified = false })) { var incident = await _incidentManager.FindByIdAsync(input.Id); incident.SignOffTime = Clock.Now; incident.SignOffUserId = AbpSession.GetUserId(); await _incidentManager.UpdateAsync(incident); unitOfWork.Complete(); } }
-
0
nice solution :)
-
0
Hello everyone @reddogaw
thank you for your solution actually i have the same situation and i tried your solution but i got an exception of type Null Reference Exception ExtendedUnitOfWorkOptions always null i don't why? i tried to inject it directly to my appservice and the same error you can see it in attached image
-
0
Hi @moustafa,
Can you share your app service code as well where you start a unitOfWork manually ?
-
0
Hi @ismcagdas
[AbpAllowAnonymous] [UnitOfWork(IsDisabled = true)] public async Task<ServiceListFullDto> GetRecord(long? id) { ServiceListFullDto entityListDto = null; if (id.HasValue) { using ( var unitOfWork = UnitOfWorkManager.Begin(new ExtendedUnitOfWorkOptions() { UpdateLastModified = false })) { var record = await _serviceRepository.GetAsync(id.Value); if (record.IsActive) { entityListDto = record.MapTo<ServiceListFullDto>(); record.Views += 1; await _serviceRepository.UpdateAsync(record); unitOfWork.Complete(); } } } return entityListDto; }
-
0
.........................................................................................................................................................................................
-
0
Hi @moustafa,
I have tried the code given by @reddogaw and it worked for me as expected with the latest AspNet Zero template. Can you send your project to <a href="mailto:[email protected]">[email protected]</a> ? So, I can take a look at your problem by code.
Thanks.
-
0
Hello,
Thank you for posting the solution.
I was looking for the same, I have a synchronization system and in this case I want not to have my LastModificationTime/CreationTime updated.
It would be nice to have this kind of option to disable AbpConcepts in Abp Framework
Regards,
-
0
Hi @moustafa, Try making GetRecord "virtual".
Hi @JeromeVoxTeneo, Try making the internal method "protected virtual". Make sure the caller method disabled UnitOfWork.