LINQ to SQL - 更新记录

7

使用C#编写asp.net 4。

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

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

我不知道如何在LINQ中做同样的事情。因此,我的工作流程如下:

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

如果我只保存'Record A',那么我最终会在数据库中得到一个新条目。

显然,只需传递Record A并执行以下操作会更好:

RecordA.Update();

我觉得我可能遗漏了什么,但是我在网上找不到一个简单明了的答案。
3个回答

2
您可以使用Table实例上的Attach方法,并通过DataContext上的SubmitChanges()方法进行提交来实现您想要的内容。
这个过程可能没有我们想象的那么简单,但您可以阅读David DeWinter的LINQ to SQL: Updating Entities以获取更详细的解释/教程。

2
假设你有一个产品类或数据库,那么你需要这样做。
    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”的Refresh方法进行刷新,Linq to SQL将从服务器获取这些实体,并进行比较,标记那些不同的实体为已更新。


谢谢,但在我的情况下,我不会真正知道用户编辑了哪些字段。因此,我必须假设所有字段都已更改并相应地编写更新。这很繁琐,但至少现在我知道我一直以来都是在按照“正确”的方式进行操作,尽管看起来似乎不是这样。 - Full Time Skeleton
无论用户编辑了哪些字段,只要您在控制器的HTTPPOST方法中将模型传递给ActionResult并调用SaveChanges(),整个记录就会在数据库中更新。 - patel.milanb
那么,是否有可能使客户端仅返回单个更改值和关键引用字段就能使其工作?比如,您将序列化记录传递给他们,他们会传回一个包含仅两个字段的更新序列化记录。到目前为止,在我的测试中,LinqToSql 尝试使用 null 覆盖现有数据。显然,这意味着您永远无法明确地将可空字段设置为 null。尝试避免编写大量的 thisfield = thatfield。 - RoboJ1M

1

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

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

我通常使用第一种选项,因为它最简单。虽然有两个DB调用的性能损失,但除非您正在进行大量更新,否则不会有影响。


谢谢,有点惊讶居然没有更好的方法。自从开始使用LINQ to SQL以来,我一直在使用“两个数据库调用”的方法,但我总是有一种隐隐的感觉,错过了一个显而易见的更简单的答案。看起来我没有,这既是好事也是坏事。 - Full Time Skeleton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接