0

我必须维护一个创建和管理报价的应用程序。(报价单是一个包含定价所需的所有信息的单一类别)。

大多数情况下,创建报价意味着在几个表格中添加几行。它非常快。然而,有时,用户会在报价单中附上大量的索赔历史记录,并且必须在数据库中创建数万行。使用 EF,它需要很长时间。

因此,我尝试使用 DbBulkCopy 批量插入声明,同时使用 EF 管理报价提醒,但我弄清楚如何实现这一点的方式真的非常麻烦:我不得不克隆报价,分离历史,从数据库中删除索赔,保存报价,获取新的外键,批量创建索赔,将历史附加回报价等。

这是实现这一目标的另一种方式吗?

注意:我可以将索赔历史与报价类分开,并使用 ADO 管理第一个,然后使用 EF 来管理,但是许多现有流程需要实际的类设计(更不用说用户实际上可以附加许多索赔历史,这,当然,是深埋在对象树中的子集合的子集合的子集合......)。

非常感谢,西尔万。

4

2 回答 2

1

我找到了一个简单的方法来完成这个:

// We will need a quotation Id (see below). Make sure we have one
SaveQuotation( myQuotation );

// Read the large claim history 
var claimCollection = ImportClaimsFromExcelFile( fileName );

// Save the claim history without using EF. The quotation Id is needed to 
// link the history to the quotation.
SaveClaimCollectionUsingSqlBulkCopy( claimCollection, myQuotation.Id );

// Now, ask EF to reload the quotation.
LoadQuotation( myQuotation.Id );

凭借 60 000 次索赔的历史记录,此代码在 10 秒内运行。使用myObjectContext.SaveChanges(), 10 分钟甚至不够...

感谢您的建议!

注意:这是我用来批量插入声明的代码:

using (var connection = new SqlConnection(constring))
{
    connection.Open();
    using (var copy = new SqlBulkCopy(connection))
    {
        copy.DestinationTableName = "ImportedLoss";
        copy.ColumnMappings.Add("ImporterId", "ImporterId");
        copy.ColumnMappings.Add("Loss", "Loss");
        copy.ColumnMappings.Add("YearOfLoss", "YearOfLoss");
        copy.BatchSize = 1000;
        copy.WriteToServer(dt); 
    }
    connection.Close();
}
于 2013-05-22T15:38:12.247 回答
0

由于为了持久化实体而对数据库进行了多次往返,因此 EF 不是批量操作的最佳选择。这说看起来像 EF 团队正在考虑改进这个http://entityframework.codeplex.com/workitem/53

另外,看看这里:http ://elegantcode.com/2012/01/26/sqlbulkcopy-for-generic-listt-useful-for-entity-framework-nhibernate/ 。另一种可能的解决方案是在单个ExecuteSqlCommand中添加所有插入,但是您将失去使用 ORM 的所有优势。

于 2013-05-16T17:40:34.727 回答