【问题标题】:Why can't I SaveChanges() to my DbContext like this?为什么我不能像这样将 SaveChanges() 保存到我的 DbContext 中?
【发布时间】:2012-11-28 20:09:59
【问题描述】:

我有一些代码用于插入一些不起作用的行:

using (MyDbContext context = new MyDbContext()) {
    foreach (Order o in FormOrders) { //That's a List<T> that got generated based on a web form
        context.Orders.Add(o);
    }
    context.SaveChanges();
}

我终于想出了如何让它工作:

foreach (Order o in FormOrders) {
    context.Orders.Add(o);
    context.SaveChanges();
}

但是,我意识到这不是很有效。诚然,一次插入的订单最多约为 40 个,但我仍然对尽可能多地使用最佳实践感兴趣。

我猜代码片段 #1 不起作用,因为 o 超出了调用 SaveChanges() 的范围,但我不明白它是如何工作得足够好来确定的,我绝对不了解它以找出更好的方法。

另外,我听说您应该为每一行使用一个新的 DbContext 实例,在上述情况下实现效率会更低。这是真的吗?

编辑

忽略这个问题。两个版本似乎都有效。我不知道是什么问题。我不会删除它,因为其他人可能会发现某些 cmets/answers 有用。

【问题讨论】:

  • foreach 语句之后将o 设置为临时变量,然后将临时变量添加到context.Orders 集合中会发生什么情况?如果您在foreach 循环之外调用SaveChanges(),它会保存吗?
  • 您遇到了什么错误?你的第一个 sn-p 的第一行应该是using (MyDbContext context = new DbContext()) {吗?
  • 没关系。也许我疯了。代码#1 现在似乎可以工作了。我发誓我昨天一整天都试过了,绝对没有插入任何东西。它从来没有抛出任何错误,只是什么也没做。还有@AntP,我的using 是正确的。

标签: asp.net sql-server asp.net-mvc database entity-framework


【解决方案1】:

我不知道您使用的是哪个上下文,但是鉴于乐观并发冲突,LINQ to SQL SubmitChanges 的行为与 LINQ to Entitie 的 SaveChanges 不同。

SubmitChanges = DataContext
SaveChanges = ObjectContext

using (MyDbContext context = new MyDbContext()) {
    foreach (Order o in FormOrders) { //That's a List<T> that got generated based on a web form
        context.Orders.Add(o);
    }
    context.SubmitChanges();
}

【讨论】:

    【解决方案2】:

    我认为您在这里处理的是闭包。

    试试这个代码是否适合你:

    using (MyDbContext context = new MyDbContext())
    {
        foreach (Order o in FormOrders)
        {
            Order localCopy = o;
            context.Orders.Add(localCopy);
        }
        context.SaveChanges();
    }
    

    简而言之,您的 Add() 方法只会执行一次。由于延迟执行,只会添加循环的最后一项。

    (引自 Jon 的文章链接如下)

    什么是闭包?

    简单地说,闭包允许你封装一些 行为,像任何其他对象一样传递它,并且仍然可以访问 到它们第一次被宣布的上下文。这使您可以 将控制结构、逻辑运算符等从 将如何使用它们的详细信息。访问的能力 原始上下文是将闭包与普通对象分开的原因, 尽管闭包实现通常使用正常来实现这一点 对象和编译器诡计。

    专家会比我更好地解释这一点:

    【讨论】:

    • 你确定吗? DbSet.Add 是同步的,所以没有关闭问题。
    • @remibourgarel:说实话,不完全确定。恐怕我还没有完全理解这个概念。但是我在类似的场景中遇到了各种奇怪的行为,ReSharper 几乎在我编写的每三个循环中都会给我警告。这就是为什么这是我的第一个想法。
    • 大部分时间是因为你使用了 lambda 表达式而延迟执行(你在循环中创建你的 lambda,但你在它之外执行它,就像我们使用 linq 表达式一样)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    相关资源
    最近更新 更多