'A second operation started on this context, Domain Event EF Core 3.1
I'm using Domain Event to update some tables. I have created a class that inherits INotificationHandlers like this:
public class DamageTypeEvents:INotificationHandler<DamageTypeWasAddedEvent>,
INotificationHandler<AttributeWasUnlinkedEvent>,
INotificationHandler<AttributeWasLinkedEvent>
{
private readonly MyContext _writeContext;
public DamageTypeEvents( MyContext writeContext )
{
_writeContext = writeContext;
}
in app service I send a list of attributes and will link and unlink these attributes to DamageTypes.
public async Task Handle( AttributeWasUnlinkedEvent notification, CancellationToken cancellationToken )
=>
//codes removed for brevity
await _writeContext.SaveChangesAsync( cancellationToken )
public async Task Handle( AttributeWasLinkedEvent notification, CancellationToken cancellationToken )
=>
//codes removed for brevity
await _writeContext.SaveChangesAsync( cancellationToken )
when AttributeWasLinkedEvent fires, then it throws following error:
A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext.
I think it can be fixed by using a DbContextFactory but EF Core 3.1 does not provide this feature.
By the way if I change the DbContext lifetime to transient it will be fixed, but I am wondering if there is any other solution?
Update:
here is how I use link and unlink in my entities.
//in command handler:
.Check( x=>x.DamageType.UnlinkAttributes( x.Attributes ) )
.Check( x=>x.DamageType.LinkAttributes(x.Attributes) )
//and in my entities
public Result LinkAttributes( List<Attribute> attributes )
{
var addedAttributes = attributes.Except( _attributes );
_attributes.AddRange( addedAttributes );
AddEvent( new AttributeWasLinkedEvent( Id));
return Result.Success();
}
public Result UnlinkAttributes( List<Attribute> attributes )
{
var unlinkedAttributes = _attributes.Except( attributes );
foreach ( var attribute in unlinkedAttributes ) {
attribute.Delete();
AddEvent( new AttributeWasUnlinkedEvent( Id,attribute.Id ));
}
return Result.Success();
}
Solution 1:[1]
This can be fixed by enabling Multiple Active Result Sets in your connection string:
string connectionString = "Data Source=MSSQL1;" +
"Initial Catalog=AdventureWorks;Integrated Security=SSPI;" +
"MultipleActiveResultSets=True";
For reference: https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/enabling-multiple-active-result-sets
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Joest |