对象状态和更改跟踪

LINQ to SQL 对象始终参与某些 状态。 例如,当 LINQ to SQL 创建新对象时,该对象处于 Unchanged 状态。 你自己创建的新对象对DataContext而言是未知的,并且处于Untracked状态。 成功执行 SubmitChanges后,LINQ to SQL 已知的所有对象都处于 Unchanged 状态。 (唯一的例外是那些已成功从数据库中删除的例外,它们处于Deleted状态,并且在该DataContext实例中不可用。)

对象状态

下表列出了 LINQ to SQL 对象的可能状态。

国家 DESCRIPTION
Untracked LINQ to SQL 无法跟踪的对象。 示例包括:

- 未通过当前 DataContext 查询的对象(例如新创建的对象)。
- 通过反序列化创建的对象
- 通过其他 DataContext 查询的对象。
Unchanged 通过使用当前 DataContext 检索到的对象,并且自创建以来未知是否已被修改。
PossiblyModified 附加到 的对象DataContext。 有关详细信息,请参阅 N 层应用程序中的数据检索和 CUD 操作(LINQ to SQL)。
ToBeInserted 使用当前 DataContext 未检索到的对象。 这会导致在 INSERT 期间执行数据库 SubmitChanges 操作。
ToBeUpdated 符合如下条件的对象:已获知自检索到该对象以来它已被修改。 这会导致在 UPDATE 期间执行数据库 SubmitChanges 操作。
ToBeDeleted 标记为删除,从而导致在 DELETE 期间执行数据库 SubmitChanges 操作的对象。
Deleted 已在数据库中删除的对象。 此状态为最终状态,不允许进行其他转换。

插入对象

您可以通过使用 Inserts 显式请求 InsertOnSubmit。 或者,LINQ to SQL 可以通过查找连接到必须更新的已知对象之一的对象来推断 Inserts 。 例如,如果将对象Untracked添加到对象EntitySet<TEntity>或将EntityRef<TEntity>设置为Untracked对象,则可以通过图形中的跟踪对象访问Untracked对象。 处理 SubmitChanges时,LINQ to SQL 会遍历跟踪的对象,并发现未跟踪的任何可访问永久性对象。 此类对象是插入数据库中的候选对象。

对于继承层次结构中的类, InsertOnSubmito) 还设置指定为 鉴别器 的成员的值以匹配对象的 o类型。 对于与默认鉴别器值匹配的类型,此作会导致使用默认值覆盖鉴别器值。 有关详细信息,请参阅 继承支持

重要

添加到 Table 中的对象不在标识缓存中。 标识缓存仅反映从数据库检索的内容。 调用 InsertOnSubmit后,添加的实体不会显示在针对数据库的查询中,直到 SubmitChanges 成功完成。

删除对象

通过对相应的 o 调用 DeleteOnSubmit(o),可以将被跟踪的对象 Table<TEntity> 标记为删除。 LINQ to SQL 将对象从 EntitySet<TEntity> 中移除视为更新操作,并将相应的外键值设置为 null。 操作的目标(o)不会被从其表中删除。 例如,cust.Orders.DeleteOnSubmit(ord) 指示一个更新,其中通过将外键 cust 设置为 null 切断了 ordord.CustomerID 之间的关系。 它不会导致删除对应于 ord的行。

当对象从表中删除 (DeleteOnSubmit) 时,LINQ to SQL 会执行以下处理:

  • 调用SubmitChanges时,将对该对象执行DELETE操作。

  • 移除操作不会传播到关联对象,无论它们是否已加载。 具体而言,不会加载相关对象来更新关系属性。

  • 成功执行 SubmitChanges后,对象将设置为 Deleted 状态。 因此,您不能在该 id 中使用此类对象或其 DataContext。 实例维护的DataContext内部缓存不会消除那些检索或作为新对象添加的对象,即便这些对象已经在数据库中被删除。

只能对由DeleteOnSubmit跟踪的对象调用DataContext。 对于对象Untracked,必须先调用Attach,然后再调用DeleteOnSubmit。 调用DeleteOnSubmitUntracked对象上将引发异常。

注释

从表中删除对象会告知 LINQ to SQL 在 DELETE 时生成相应的 SQL SubmitChanges 命令。 此作不会从缓存中删除对象或将删除内容传播到相关对象。

若要回收 id 已删除的对象,请使用新 DataContext 实例。 若要清理相关对象,可以使用数据库的 级联删除 功能,或者手动删除相关对象。

无需按任何特殊顺序删除相关对象(与数据库中不同)。

更新对象

可以通过观察更改通知来检测 Updates 。 通知是通过属性 setter 中的 PropertyChanging 事件提供的。 当 LINQ to SQL 收到对对象第一次更改的通知时,它会创建对象的副本,并将对象视为生成 Update 语句的候选对象。

对于未实现 INotifyPropertyChanging的对象,LINQ to SQL 维护对象首次具体化时具有的值的副本。 调用 SubmitChanges时,LINQ to SQL 比较当前值和原始值,以确定对象是否已更改。

对于关系的更新,从子级到父级的引用(即与外键对应的引用)被视为授权。 反向引用(即从父到子)是可选的。 关系类(EntitySet<TEntity>EntityRef<TEntity>)保证双向引用对于一对多关系和一对一关系是一致的。 如果对象模型未使用 EntitySet<TEntity> ,或者 EntityRef<TEntity>,如果存在反向引用,则你有责任在更新关系时与前向引用保持一致。

如果您既更新所需的引用,又更新对应的外键,则必须确保它们一致。 InvalidOperationException如果在调用SubmitChanges时两者未同步,则会引发异常。 尽管外键值更改足以影响基础行的更新,但应更改引用以保持对象图的连接和关系的双向一致性。

另请参阅