C# 如何提高实体框架单位的工作绩效

C# 如何提高实体框架单位的工作绩效,c#,sql-server,performance,entity-framework,C#,Sql Server,Performance,Entity Framework,请看以下情况: 我确实有一个CSV文件,其中导入了几个字段(并非所有字段都在SQL server中使用实体框架和工作单元和存储库设计模式) 现在,唯一标识记录的方法是检查4个字段:GlnCode、Description、VendorID和项目编号 因此,在插入记录之前,我需要检查是否存在: var unitOfWork = new UnitOfWork(new AppServerContext()); // If the article is already existing, updat

请看以下情况:

我确实有一个CSV文件,其中导入了几个字段(并非所有字段都在SQL server中使用实体框架和工作单元和存储库设计模式)

现在,唯一标识记录的方法是检查4个字段:
GlnCode
Description
VendorID
项目编号

因此,在插入记录之前,我需要检查是否存在:

 var unitOfWork = new UnitOfWork(new AppServerContext());

 // If the article is already existing, update the vendor name.
 if (unitOfWork.GenericArticlesRepository.GetAllByFilter(
         x => x.GlnCode.Equals(newGenericArticle.GlnCode) &&
              x.Description.Equals(newGenericArticle.Description) &&
              x.VendorId.Equals(newGenericArticle.VendorId) &&
              x.ItemNumber.Equals(newGenericArticle.ItemNumber)).Any())
 {
     var foundArticle = unitOfWork.GenericArticlesRepository.GetByFilter(
         x => x.GlnCode.Equals(newGenericArticle.GlnCode) &&
              x.Description.Equals(newGenericArticle.Description) &&
              x.VendorId.Equals(newGenericArticle.VendorId) &&
              x.ItemNumber.Equals(newGenericArticle.ItemNumber));

     foundArticle.VendorName = newGenericArticle.VendorName;

     unitOfWork.GenericArticlesRepository.Update(foundArticle);
 }
如果它存在,我需要更新它,您可以在上面的代码中看到

现在,您需要知道,我正在导入大约150万条记录,所以导入量很大。 正是这个过滤器使CPU达到了几乎100%

“GetAllByFilter”方法非常简单,可以执行以下操作:

return !Entities.Any() ? null : !Entities.Where(predicate).Any() ? null : Entities.Where(predicate).AsQueryable();
其中
谓词
等于
表达式

我能做些什么来确保服务器的CPU不会达到100%吗

注意:我使用的是SQL Server 2012


您是否对数据库中的这四个字段编制了索引?这是我要做的第一件事

好的,我建议您尝试以下方法:

总之,, 不要在每次插入或更新后调用SaveChanges()。相反,每隔1-2k调用一次记录,以便对数据库进行批量插入/更新

此外,还可以选择更改上下文中的以下参数:

yourContext.Configuration.AutoDetectChangesEnabled = false;
yourContext.Configuration.ValidateOnSaveEnabled = false;

任务的工具错误。您不应该一次处理一百万条以上的记录。使用bulk Insert and clean(如果需要)将记录插入临时表,然后使用存储过程以基于集合的方式进行处理,或者使用为此而设计的工具SSIS

我找到了另一个没有在这里提出的解决方案,所以我将回答我自己的问题


我将有一个临时表,其中我将导入所有数据,导入后,我将执行一个存储过程,该过程将执行
Merge
命令来填充destinatio表。我相信这是最有效的。

还没有做到。我马上就可以。我不明白我怎么会错过。您还有其他想法吗?字段现在是索引,但问题仍然是一样的。我有一个表有4个键(使记录唯一的4列)。在那之后,我为这4个键创建了一个索引,但问题仍然存在。在这种情况下,您可能希望将存储过程与MERGE语句一起使用。您可以从实体Framework调用存储过程,我会尝试一下,但这会提高性能,因为我仍然需要为要导入的文件中的每个记录执行SP。也就是说,1.500.000次对存储过程的调用?不,可以使用表值参数并成批发送。我建议你,或者试试看你为什么这么高兴?对于每个插入,您实际上要查询数据库10次。现在,可以肯定的是,Any倾向于使用EXISTS查询,但它仍然是一个查询。特别是,先调用Entities.Any(),然后调用谓词上的Any,然后返回iqueryable,然后再次调用该谓词上的Any!嘘。但除此之外,英孚不是为这个设计的。。它不是批处理或批量作业处理器。。。改为使用SqlBulkCopy类。@ErikFunkenbusch有没有关于如何摆脱
Any()
实现以提高其性能的建议?是的,只需使用where子句执行一个查询,并使用SingleOrDefault执行四个条件(假设它只能返回一条记录),如果它为null,则表示它不存在,所以跳过更新。
yourContext.Configuration.AutoDetectChangesEnabled = false;
yourContext.Configuration.ValidateOnSaveEnabled = false;