FirebirdSQL / NETProvider

Firebird ADO.NET Data Provider
https://firebirdsql.org/en/net-provider/
Other
161 stars 66 forks source link

Error System.IndexOutOfRangeException: Index was outside the bounds of the array #1170

Closed DenMpei closed 7 months ago

DenMpei commented 7 months ago

Good day! I'm using the library FirebirdSql.EntityFrameworkCore.Firebird with FirebirdSql.Data.FirebirdClient version 9.1.1. I need to run several queries in parallel. For this purpose I create separate contexts (since DbContext is not thread-safe). But in order to somehow unload the database, I use one connection with one reading transaction. As specified in Microsoft Help (https://learn.microsoft.com/en-us/ef/core/saving/transactions). But when I run several requests I get an error: System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Collections.Generic.HashSet1.AddIfNotPresent(T value, Int32& location) at System.Collections.Generic.HashSet1.Add(T item) at FirebirdSql.Data.FirebirdClient.FbConnectionInternal.AddPreparedCommand(IFbPreparedCommand command) at FirebirdSql.Data.FirebirdClient.FbCommand.Prepare(Boolean returnsSet) at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior behavior, Boolean returnsSet) at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(CommandBehavior behavior) at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader() at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.Enumerator.InitializeReader(Enumerator enumerator) `

This occurs because the FbConnectionInternal (FbConnectionInternal.cs) uses a non-thread-safe hash. Is it possible to fix this in the next version?

Regards

cincuranet commented 7 months ago

FbConnection/ADO.NET is not thread-safe as well. So you should not use connection from multiple threads, same as for DbContext.