【问题标题】:How to bulk find/match and update records using LINQ?如何使用 LINQ 批量查找/匹配和更新记录?
【发布时间】:2018-02-11 17:56:51
【问题描述】:

基本上,我在数据库中有一个 Items 表,其中需要经常更新项目的库存。我在 XML 提要中有更新的库存值。

这并不一定意味着表中的项目数和 XML 提要必须相同。我目前在数据库中有大约 9K 个项目,在 XML 中有 72K 个项目。

到目前为止,这是我尝试过的:

Using context As New QuotationDbContext
    For Each item In context.Items.Where(Function(i) i.Active)
        Dim matchedNode = 
            xDoc.Descendants("item").   'xDoc is an XDocument object.
                 FirstOrDefault(Function(n) n.Attribute("itemcode").Value = item.ItemNumber)
        If matchedNode IsNot Nothing Then item.Stock = matchedNode.Attribute("stock").Value
    Next
    context.SaveChanges()
End Using

..反之亦然:

Using context As New QuotationDbContext
    For Each itemNode In xDoc.Descendants("item")
        Dim itemNumber As String = itemNode.Attribute("itemcode").Value
        Dim matchedItem = context.Items.FirstOrDefault(Function(i) i.Active AndAlso
                                                                   i.ItemNumber = itemNumber)
        If matchedItem IsNot Nothing Then matchedItem.Stock = itemNode.Attribute("stock").Value
    Next
    context.SaveChanges()
End Using

问题在于,这两种方法都需要 2 分钟多一点的时间来完成“匹配和更新”,而更新所有项目需要几百毫秒,因此很明显,匹配是花费所有时间的原因。

那么,有没有更好(更快)的方法来批量匹配/查找数据库中的记录以进行更新?

我认为我的问题的解决方案更有可能是纯 LINQ 解决方案不一定连接到 EF。不过,我想提供完整的上下文,以防我遗漏了什么。

P.S.虽然我的代码是用 VB 编写的,但我也非常感谢任何使用 C# 代码的答案。

【问题讨论】:

  • 不是答案,但我已将其用于批量操作,它似乎有效:github.com/zzzprojects/EntityFramework.Extended
  • 不错的批量更新/批量删除库,但我的要求不同。我认为我的问题的解决方案更有可能是纯 LINQ 解决方案不一定连接到 EF。我想提供完整的上下文,以防万一我遗漏了什么。

标签: c# .net vb.net entity-framework linq


【解决方案1】:

我认为这主要是算法问题。 您花费大量时间在 xml 中查找项目。 这里:

Dim matchedNode = 
        xDoc.Descendants("item").
             FirstOrDefault(Function(n) n.Attribute("itemcode").Value = item.ItemNumber)

例如,尝试将所有项目从您的 xml 获取到字典中。因为字典花费 O(1) 时间来查找元素。它会是这样的(我没有IDE来尝试这个代码)

Dim dict = xDoc.Descendants("item").ToDictionary(Function(n) n.Attribute("itemcode").Value)

Using context As New QuotationDbContext
    For Each item In context.Items.Where(Function(i) i.Active)
        If dict.ContainsKey(item.ItemNumber) Then
            item.Stock = dict(item.ItemNumber).Attribute("stock").Value
        End If
    Next
    context.SaveChanges()
End Using

【讨论】:

  • 我怎么这么笨!很好用Dictionary,谢谢!让我稍微编辑一下您的代码以使其编译。
【解决方案2】:

您可以尝试Merge 选项。我将在实体上下文中创建一个具有合并实现和import 的存储过程。 如果实施得当,这可能会给你最好的性能结果。

【讨论】:

  • 嗯,以前从未使用过代码优先的 SP。不过会试一试,谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-11-13
  • 2021-08-03
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
相关资源
最近更新 更多