I'm having some issues scoping Entity Framework using Ninject within an Azure Function.
I keep getting random object already disposed and internal EF errors, such as the following, which leads me to believe the DbContext
is being shared between threads:
I'm not sure if this is getting scoped wrong, or if i only need to be calling _kernal.Load()
once per app domain. Any insight would be greatly appreciated.
An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary'2.Insert(TKey key, TValue value, Boolean add)
at System.Data.Entity.Core.Objects.ObjectStateManager.AddStateManagerTypeMetadata(EntitySet entitySet, ObjectTypeMapping mapping)
at System.Data.Entity.Core.Objects.ObjectStateManager.GetOrAddStateManagerTypeMetadata(Type entityType, EntitySet entitySet)
at System.Data.Entity.Core.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func'2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator'1.ReadNextElement(Shaper shaper)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.RowNestedResultEnumerator.MaterializeRow() at System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.RowNestedResultEnumerator.MoveNext() at System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.ObjectQueryNestedEnumerator.TryReadToNextElement() at System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.ObjectQueryNestedEnumerator.MoveNext() at System.Data.Entity.Internal.LazyEnumerator'1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable'1 source)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.b__1[TResult](IEnumerable'1 sequence)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable'1 query, Expression queryRoot)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable'1 source, Expression`1 predicate)
at MyApp.DAO.Implementations.LoanRepository.Get(Int32 loanId) in d:\a\1\s\MyApp\MyApp.DAO\Implementations\LoanRepository.cs:line 50
at MyApp.DAO.Implementations.LoanRepository.Get(String loanGuid) in d:\a\1\s\MyApp\MyApp\Implementations\LoanRepository.cs:line 0
at MyApp.BL.Los.MyManager.d__22.MoveNext()
and
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
at System.Data.Entity.Core.Objects.ObjectContext.ReleaseConnection() at System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.Finally() at System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.SimpleEnumerator.Dispose() at System.Data.Entity.Internal.LazyEnumerator`1.Dispose() at MyApp.DAO.Implementations.PromotionRepository.getAllActivePromotions(Int32 LoanID) in d:\a\1\s\MyApp\MyApp.DAO\Implementations\PromotionRepository.cs:line 56 at MyApp.DAO.Implementations.LoanRepository.Get(Int32 loanId) in d:\a\1\s\MyApp\MyApp.DAO\Implementations\LoanRepository.cs:line 204 at MyApp.DAO.Implementations.LoanRepository.Get(String loanGuid) in d:\a\1\s\MyApp\MyApp.DAO\Implementations\LoanRepository.cs:line 0 at MyApp.BL.Los.MyManager.d__22.MoveNext() in d:\a\1\s\MyApp\MyApp.BL.Los\MyManager.cs:line 63
Ninject Configuration
public class NinjectBindings : NinjectModule
{
public override void Load()
{
Bind<MyDBContext>().ToSelf().InSingletonScope().WithConstructorArgument("connectionString", "name=MyDB");
}
}
Azure Function
[FunctionName("ProcessData")]
public static async Task ProcessData([QueueTrigger("myqueue", Connection = "AzureWebJobsStorage")]string message, int dequeueCount, ILogger log, ExecutionContext context)
{
using (StandardKernel _kernal = new StandardKernel())
{
_kernal.Load(Assembly.GetExecutingAssembly());
// do work
}
}
InSingletonScope
? Do you even know what a Singleton is? – Illinoisawait
ed. Furthermore, all EF code is synchronous calls. – Alum