实体框架5螺纹敏捷

实体框架5螺纹敏捷

本文介绍了实体框架5螺纹敏捷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的EntityFramework code深处时将引发NullReferenceException(EF错误?),但我的问题是关于实体框架(V5)和异步的WebAPI控制器动作。

一个摄制将很难重新在这里,但在本质上code执行以下操作:

 公共类AController:ApiController
{
    私人IUow _uow;除其他事项外//,一个的DbContext
    // DI构造函数
    公共AController(IUow UOW)
    {
        _uow = UOW;
    }    [HttpPost]
    公共异步任务< Htt的presponseMessage>帖子(型号模型)
    {
        实体E = _uow.Entity.GetById(model.id);
        等待IO_Ops_Async(模型);
        新ModelAdapter()UpdateEntity(实体模型​​);
        _uow.Commit(); < - 抛出的异常此调用过程 - 见下文
        ... //做一些与返回结果
    }
}

提交(),前刚刚 DbContext.SaveChanges(),我们通过所有<$ C $循环C> DbChangeTracker.Entries()来设置一些常用的属性。不过这是项()与单个循环之前误差的的NullReferenceException 内心深处 System.Data.Entity.Infrastructure.DbChangeTracker.Entries()

下面是调用堆栈。这是所有框架code和感觉就像一个错误,但我的问题确实是如果两者之间的DbContext呼叫允许上述异步/等待使用。在任何时候,我们多线程 - 异步/的await只用,因为有我们可以使用异步/的await设施(一对夫妇的HttpClient下载+一些异步磁盘I / O的)

执行一些IO操作。

  System.NullReferenceException:对象不设置到对象的实例\\ r \\ n。
在System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity,布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.EntityReference`1.Include(布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity,布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity,布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.EntityCollection`1.Include(布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity,布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity,布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.EntityReference`1.Include(布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity,布尔addRelationshipAsUnchanged,布尔doAttach)\\ r \\ n
在System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget,布尔applyConstraints,布尔addRelationshipAsUnchanged,布尔relationshipAlreadyExists,布尔allowModifyingOtherEndOfRelationship,布尔forceForeignKeyChanges)\\ r \\ n
在System.Data.Objects.ObjectStateManager.PerformAdd(IEntityWrapper wrappedOwner,RelatedEnd relatedEnd,IEntityWrapper entityToAdd,布尔isForeignKeyChange)\\ r \\ n
在System.Data.Objects.ObjectStateManager.PerformAdd(IList`1项)\\ r \\ n
在System.Data.Objects.ObjectStateManager.DetectChanges(个)\\ r \\ n
在System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate个)\\ r \\ n
在System.Data.Entity.Infrastructure.DbChangeTracker.Entries(个)\\ r \\ n


解决方案

有后的隐式线程切换等待,造成IO完成。据我所知,EF5可能无法处理这种因为它使用线程本地存储。

OTOH,EF6.x(特别是最新版本)应该是在这种情况下正常工作。

相关:

更新以报告的评价:

The EF5 source code is not open-sourced (unlike with EF6), so I cannot be 100% sure, but I suspect EF5 explicitly uses TLS (i.e., ThreadStatic or ThreadLocal<T>). There is no way all TLS properties could be automatically flowed by ExecutionContext. It would be a huge breaking change and security threat to the existing code (let alone it might not even be technically possible to implement this).

ExecutionContext captures and flows a very specific subset of thread properties. This subset is undocumented, but you can learn more about it here.

It's a responsibly of the specific class implementation to flow its static properties across multiple threads, there's CallContext.LogicalSetData/CallContext.LogicalGetData for that. I believe this is what EF6 does under the hood.

这篇关于实体框架5螺纹敏捷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 14:30