【问题标题】:LINQ to SQL - updating recordsLINQ to SQL - 更新记录
【发布时间】:2012-07-02 15:06:58
【问题描述】:

通过 C# 使用 asp.net 4。

在我的数据访问层中,我有保存和更新记录的方法。保存很简单,但更新很繁琐。

我以前使用过 SubSonic,它非常棒,因为它有活动记录,并且知道如果我加载记录、更改一些条目然后再次保存它,它会将其识别为更新并且不会尝试保存新条目在数据库中。

我不知道如何在 LINQ 中做同样的事情。结果我的工作流程是这样的:

  1. 网页从数据库中获取“记录 A”
  2. 其中的一些值由用户更改。
  3. “记录 A”被传回数据访问层
  4. 我现在需要再次加载记录 A,将其称为“SavedRecord A”,使用传递的“记录 A”中的值更新此对象中的所有值,然后更新/保存“SavedRecord A”!

如果我只是保存“记录 A”,我最终会在数据库中获得一个新条目。

显然,只通过记录 A 并执行以下操作会更好:

RecordA.Update();

我假设我在这里遗漏了一些东西,但我在网上找不到直接的答案。

【问题讨论】:

    标签: asp.net sql linq


    【解决方案1】:

    您可以使用Table 实例上的Attach method 完成您想要的操作,并通过DataContext 上的SubmitChanges() 方法提交。

    此过程可能不像我们希望的那样简单,但您可以阅读 David DeWinter 的 LINQ to SQL: Updating Entities 以获得更深入的解释/教程。

    【讨论】:

      【解决方案2】:

      假设您有一个产品类 OR DB,那么您将不得不这样做。

          DbContext _db = new DbContext();
      
          var _product = ( from p in _db.Products
                                          where p.Id == 1  // suppose you getting the first product
                                          select p).First();  // this will fetch the first record.
      
           _product.ProductName = "New Product";
      
           _db.SaveChanges();
      
            // this is for EF LINQ to Objects
           _db.Entry(_product).State = EntityState.Modified;  
           _db.SaveChanges();
      
      -------------------------------------------------------------------------------------
      this is another example using Attach
      -------------------------------------------------------------------------------------
      
      public static void Update(IEnumerable<Sample> samples , DataClassesDataContext db)
      {
          db.Samples.AttachAll(samples);
          db.Refresh(RefreshMode.KeepCurrentValues, samples)
          db.SubmitChanges();
      }
      

      如果您将实体附加到上下文,然后刷新(选择 KeepCurrentValues),Linq to SQL 将从服务器获取这些实体,比较它们,并将不同的实体标记为更新

      【讨论】:

      • 谢谢,在我的情况下,虽然我真的不知道哪些字段发生了变化,因为用户将进行编辑。因此,我必须假设所有字段都已更改并相应地编写更新。这很乏味,但至少我现在知道我一直在以“正确”的方式做这件事,即使它看起来不像。
      • 用户编辑了哪些字段并不重要,只要您在HTTPPOST方法中将模型传递给控制器​​中的ActionResult并调用SaveChanges(),整个记录都会在数据库。
      • 那么,是否有可能在客户端只传回一个更改的值+一个键引用字段的情况下进行这项工作?假设您向他们传递了一个序列化记录,并且他们传回了一个仅包含两个字段的更新序列化记录。到目前为止,在我的测试中,LinqToSql 只是尝试用空值覆盖现有数据。显然,这意味着您将永远无法显式地将可为空的字段设为空。尽量避免写很多 thisfield = thatfield。
      【解决方案3】:

      当 LINQ-to-SQL 更新数据库中的记录时,它需要确切知道哪些字段已更改,以便仅更新这些字段。你基本上有三个选择:

      • 当更新的数据回传到 Web 服务器时,从数据库加载现有数据,将所有属性分配给加载的对象并调用 SubmitChanges()。任何分配了现有值的属性都不会更新。
      • 跟踪对象的未修改状态并将Attach 与未修改和已修改值一起使用。
      • 使用乐观并发检查所需的所有状态初始化一个新对象(如果启用,默认情况下)。然后附加对象,最后在附加之后更新任何更改的属性,以使 DataContext 更改跟踪器知道这些更新。

      我通常使用第一个选项,因为它最简单。两次数据库调用会降低性能,但除非您进行大量更新,否则这无关紧要。

      【讨论】:

      • 谢谢,没有比这更好的方法了,这有点令人惊讶。自从开始使用 LINQ to SQL 以来,我一直在使用“两个 DB 调用”方法,但我一直有一种烦人的感觉,我错过了一个明显更容易的答案。看来我没有,这有好有坏。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多