在Azure函数中使用Ninject确定实体框架

Cam*_*uce 6 c# entity-framework ninject azure azure-functions

我在Azure函数中使用Ninject确定实体框架的一些问题.

我一直在处理随机对象和内部EF错误,例如以下内容,这让我相信DbContext在线程之间共享:

我不确定这是否是错误的,或者我只需要_kernal.Load()每个应用程序域调用一次.任何见解将不胜感激.

An item with the same key has already been added.


System.Data.Entgument.EhgumentAception(ExceptionResource资源)处于System.Data.Entity.Core.Objects.ObjectStateManager.AddStateManagerTypeMetadata(EntitySet entitySet,System.Collections.Generic.Dictionary'2.Insert(TKey key,TValue value,Boolean add)的System.ThrowHelper.ThrowArgumentException(ExceptionResource资源)ObjectTypeMapping映射)
在System.Data.Entity.Core.Objects.ObjectStateManager.GetOrAddStateManagerTypeMetadata(类型的EntityType,EntitySet的EntitySet的)
在System.Data.Entity.Core.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject,的EntityKey passedKey,EntitySet的EntitySet的,字符串argumentName ,
在System.Data.Entity.Cnt.Comn.Internal.Materialization.Shaper.HandleEntityAppendOnly [TEntity](Func'2 constructEntityDelegate,EntityKey entityKey,EntitySet entitySet
)
处于System.Data.Entity的lambda_method(Closure,Shaper)处,
System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.RowNestedResultEnumerator.Materi中的.Core.Common.Internal.Materialization.Coordinator'1.ReadNextElement(Shaper shaper)System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.ObjectQueryNestedEnumerator.TryReadToNextElement中System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.RowNestedResultEnumerator.MoveNext()的alizeRow() )System.Data.Entity.Core.Inter.Materialization.Shaper'1.ObjectQueryNestedEnumerator.MoveNext()
在System.Linq.Enumerable.FirstOrDefault的System.Data.Entity.Internal.LazyEnumerator'1.MoveNext()处.
在System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle的System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.b__1 [TResult](IEnumerable'1序列)的TSource](IEnumerable'1 source)
[
在System.Data.Entity.Internal.Linq的System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute [TResult](表达式表达式)
中的TResult](IEnumerable'1查询,表达式queryRoot).DbQueryProvider.Execute [TResult](表达式表达式)
在System.Linq.Queryable.FirstOrDefault [TSource](IQueryable'1 source,Expression` 1个谓词)
在MyApp.DAO.Implementations.LoanRepository.Get(Int32 loanId)的d:\ a\1\s\MyApp\MyApp.DAO\Implementations\LoanRepository.cs:第50行,
位于MyApp.DAO.Implementations.LoanRepository.获取(String loanGuid)在d:\ a\1\s\MyApp\MyApp\Implementations\LoanRepository.cs:
MyApp.BL.Los.MyManager.d__22.MoveNext()中的第0行

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

在System.Data.Entity.Core.Con.Con.Comn.Inter.Mon中的System.Data.Entity.Cor.Common.Inter.Materialization.Shaper'1.Finally()处的System.Data.Entity.Core.Objects.ObjectContext.ReleaseConnection()处. .Materialization.Shaper'1.SimpleEnumerator.Dispose()在D:\ a\1 \的MyApp.DAO.Implementations.PromotionRepository.getAllActivePromotions(Int32 LoanID)中的System.Data.Entity.Internal.LazyEnumerator`1.Dispose() s\MyApp\MyApp.DAO\Implementations\PromotionRepository.cs:位于d:\ a\1\s\MyApp\MyApp.DAO\Implementations\LoanRepository中的MyApp.DAO.Implementations.LoanRepository.Get(Int32 loanId)的第56行. cs:MyApp.DAO.Implementations.LoanRepository.Get(String loanGuid)中的第204行,位于d:\ a\1\s\MyApp\MyApp.DAO\Implementations\LoanRepository.cs:MyApp.BL.Los.MyManager中的第0行.d__22.MoveNext()在d:\ a\1\s\MyApp\MyApp.BL.Los\MyManager.cs:第63行

Ninject配置

 public class NinjectBindings : NinjectModule
    {
        public override void Load()
        {
            Bind<MyDBContext>().ToSelf().InSingletonScope().WithConstructorArgument("connectionString", "name=MyDB");
        }
    }
Run Code Online (Sandbox Code Playgroud)

Azure功能

[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
   }
}
Run Code Online (Sandbox Code Playgroud)

Bru*_*hen 3

根据您的描述,我使用了您的代码,发现以下代码可以按预期工作。

using (StandardKernel _kernal = new StandardKernel())
{
    _kernal.Load(Assembly.GetExecutingAssembly());

    // do work
    BruceDbContext ctx = _kernal.Get<BruceDbContext>();
    var todoitem = ctx.TodoItems.FirstOrDefault();
    log.Info(JsonConvert.SerializeObject(todoitem));
}
Run Code Online (Sandbox Code Playgroud)

ObjectContext 实例已被释放,不能再用于需要连接的操作。System.Data.Entity.Core.Common.Internal.Materialization.Shaper'1.SimpleEnumerator.Dispose() 在 System.Data.Entity.Internal。LazyEnumerator `1.Dispose()

我假设错误是在使用 EF 时从您的操作中引发的。您需要确保在处置 DbContext 之前访问延迟加载导航属性。这里有一个类似的问题,你可以参考一下。一般来说,您需要检查您的代码,并尝试根据异常的完整 StackTrace 找到导致此问题的特定代码行。或者,您可以使用有关错误的更多详细信息以及您用于缩小此问题范围的代码来更新您的问题。

此外,Azure Functions 不支持类似于 Webjobs 的 DI。另外,我发现了github问题。此外,您可以使用范围服务在功能级别上遵循 Azure Functions 中正确的依赖关系注入!以及Azure Functions 中函数级别的依赖项注入