我在一个非常大的应用程序中从ObjectContext更改为DbContext(数据库优先)后,我的服务器对Garbage Collector感到疯狂,性能很乱,很多无法访问,超时,并且出现了各种令人讨厌的错误。< / p>
在阅读了批次并对服务器进行了分析后,发现50%的处理器时间都在Find方法上,因此我删除了使用Find for GetById实际调用find但将AutoDetectChanges变为false然后为true。这是第一次实际上大大改善了性能的调整。
之后我描述并看到两种方法被大量使用。两者都是Get of large collections(想象一下有很多关系的GetProduct)
走到那些方法并做同样的事情,(获取数据时AutoDetectChanges为false)。
这些方法是只读的,所以我认为关闭AutoDetectChanges是安全的。
之前,使用ObjectContext,应用程序可以顺利运行。 事实是,我们的代码很像:
var someEntityDTO = service.GetSomeEntityDTO(...) // Get a DTO
service.SomeLogic(someEntityDTO) // Perform some logic, update, whatever.
someEntityDTO.CreateUpdate();
DTO上的CreateUpdate方法会将所有属性从DTO映射到实体,保存更改并返回实体。
签名与此类似:public SomeEntity CreateUpdate(){
var someEntity = context.FindById(Id);
if (someEntity == null)
var someEntity = context.SomeEntities.Create();
someEntity.Name = Name;
someEntity.OtherProperty = OtherProperty
someEntity.OtherEntityCollection = OtherEntityCollectionDTO.CreateUpdate();
// .... BIG ETC (including relations and lot of nasty stuff :D
context.SaveChanges();
}
加载集合时,它是这样的:
var entitiesDTOs = service.GetSomeEntityList();
伪GetSomeEntityList中的代码是这样的:
var ret = context.SomeEntities.Where( .... )
return ret.Select(x => new SomeEntityDTO(x));
和DTO的构造函数如下:
public SomeEntityDTO(SomeEntity entity) {
Id = entity.Id;
Name = entity.Name;
OtherEntityDTO = new OtherEntityDTO(entity.OtherEntity);
AnotherEntitiesDTO = entity.AnotherEntities.Select(x=> new AnotherEntityDTO(x));
// ... ETC with more properties and Navigation.
}
据我了解,在跟踪大量对象时,这些映射对于EF 6 DbContext来说是不可行的。
另一个兴趣点是为每个Web请求创建了DbContext,并传递了所有被调用的方法。
因此,不是上面提到的DTO集合的代码,真正的代码更像是:
entity.AnotherEntities.Select(x=> new AnotherEntityDTO(context, x));
虽然我可以通过调整来提高性能,但我正在寻找一些建议,注意事项,帮助或评论为什么我的应用程序从平滑到混乱,以及如何改进代码实践以达到&#39;平滑&#39;再说一遍。
我试图简化大部分代码(它不是真正的代码)只是为了简洁/清晰。如果您需要更多信息,请不要犹豫。
简化的Arquitecture是:MVC(n) - &gt; WCF - &gt; BLL - &gt; DAL(DbContext)|实体(POCO) 多个MVC应用程序使用主WCF服务,该服务调用包含业务逻辑的DLL,dbcontext在另一层(DAL)上。实体是单独项目中的POCO类。