建议在Entity Framework 4中使用临时表或表变量。更新性能实体框架

时间:2011-02-19 16:41:11

标签: c# sql-server-2008 entity-framework-4 temp-tables

我需要更新表中的位字段,并将该字段设置为true,以获取该表中特定的ID列表。

Ids从外部进程传入。

我想在纯SQL中最有效的方法是创建一个临时表并用Ids填充它,然后用这个连接主表并相应地设置位字段。

我可以创建一个SPROC来接收Ids,但是可能涉及需要这个标志的200-300,000行,所以它可能不是最有效的方式。使用IN语句限制了可以传递的数据量和性能。

如何使用实体框架

实现上述目标

我想可以创建一个SPROC来创建一个临时表,但从模型的角度来看,这不存在。

有没有办法在运行时动态添加实体。 [或者这种方法会引起头痛]。

我正在做出上述假设,虽然填充300,000行的临时表并进行连接比调用SPROC 300,000次更快:) [Ids是Guids]

我是否应该考虑另一种方法。

2 个答案:

答案 0 :(得分:16)

对于300k行的数据卷,我会忘记EF。我会通过如下表格来做到这一点:

BatchId  RowId

其中RowId是我们想要更新的行的PK,而BatchId只是引用300k行的“运行”(允许一次多个等)。

我会生成一个新的BatchId(这可能是任何独特的-Guid跳出来的想法),并使用SqlBulkCopy将te记录插入此表,即

100034   17
100034   22
...
100034   134556

然后我会使用一个simgle sproc进行连接和更新(并从表中删除批处理)。

SqlBulkCopy是将这一数据量提供给服务器的最快方法;你不会淹没在往返旅行中。 EF是面向对象的:适用于很多场景 - 但不是这个场景。

答案 1 :(得分:4)

我将Marcs的回复作为答案,但我想详细介绍一下我们如何实施这一要求。 Marc的回应极大地帮助我们制定了解决方案。

我们必须处理一个目标/指南,以便在不使用SPROCS的情况下保留在实体框架内,尽管我们的解决方案可能不适合其他已为我们工作的

我们在数据库中使用BatchId [uniqueidentifier]和ItemId varchar列创建了一个Item表。

此表已添加到EF模型中,因此我们没有使用临时表。

在上传这些ID时,这个表填充了Ids [插入很快我们发现使用EF]

然后我们使用context.ExecuteStoreCommand运行SQL来连接项表和主表,并更新主表中的位字段,以获取专门为该会话创建的批处理ID的记录。

我们最终清除了这个batchId的表。

我们有表现,保持在我们没有SPROC目标。 [我们不同意:)但它是一个民主国家]

我们的确切要求稍微复杂一点,但是如果需要使用Entity框架获得良好的更新性能,只要我们有特定的限制就可以正常工作。

利安