我正在使用EF 4.1(代码优先)。我需要根据Excel文件中的数据在数据库中添加/更新产品。在这里讨论,实现此目的的一种方法是使用dbContext.Products.ToList()强制从数据库加载所有产品,然后使用db.Products.Local.FirstOrDefault(...)来检查Excel中的产品是否存在于数据库中相应地进行插入或添加。这只是一次往返。
现在,我的问题是数据库中有两个产品,因此无法在内存中加载所有产品。如何在不增加往返数据库的情况下实现这一目标的方法是什么。我的理解是,如果我只是使用db.Products.FirstOrDefault(...)搜索每个要处理的excel产品,那么即使我多次为完全相同的产品发出语句,这也会执行每次往返! EF缓存对象的目的是什么,如果它仍然进入数据库,则返回缓存的值!
答案 0 :(得分:1)
实际上没有办法让这更好。 EF对于这类任务来说不是一个好的解决方案。您必须知道数据库中是否已存在产品才能使用正确的操作,因此您始终需要执行其他查询 - 您可以使用.Contains
将多个产品分组到单个查询(如SQL IN
),但这只会解决检查问题。更糟糕的问题是每个INSERT
或UPDATE
也在单独的往返中执行,并且没有办法解决这个问题,因为EF不支持命令批处理。
创建存储过程并将有关产品的信息传递给该存储过程。存储过程将根据数据库中记录的存在执行插入或更新。
您甚至可以使用一些更高级的功能(如表值参数)将多个记录从excel传递到单个调用的过程或将Excel导入临时表(例如使用SSIS)并直接在SQL服务器上处理它们。最后,您可以使用批量插入将所有记录获取到特殊导入表,并使用单个存储过程调用再次处理它们。