2013-05-16 22 views
0

我必须维护一个创建和管理报价的应用程序。 (报价是包含定价所需信息的单一类别)。有没有办法使用EF来管理实体框架对象的一部分,其余部分使用ADO?

大多数情况下,创建报价意味着将几行添加到几个表中。它非常快。然而,有时候,用户会对报价提出大量索赔,并且必须在数据库中创建数以万计的行。使用EF,它需要永远。

所以我试图使用DbBulkCopy来批量插入声明,同时使用EF来管理报价的提醒,但我想出如何实现这一点的方式真的很麻烦:我不得不克隆报价,分离历史记录,从数据库中删除索赔,保存报价,获取新的外键,批量创建索赔,将历史记录返回到报价单等。

是另一种实现此目的的方法吗?

注意:我可以将声明历史从Quotation类中分离出来,并使用ADO管理第一个,而使用EF管理第一个,但很多现有流程需要实际的类设计(更不用说用户可以实际连接很多索赔历史记录,当然,这些历史记录是深埋在对象树中的子集合子集合的子集合...)。

非常感谢, Sylvain。

+0

这是更多钞票来尝试存储过程的方法吗? – Jonathan

+0

感谢您的建议。但据我所知,我将不得不使用存储过程保存整个对象。正如Giorgio指出的那样,我会放弃使用ORM的优势... – SRO

回答

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(); 
} 
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的所有优点。

+0

感谢您的回答。你的解决方案(一个单一的sql命令)可以工作,但正如你写的那样,我会失去EF的优势。我不能等待下一个EF版本:)干杯。 – SRO

相关问题