`
izuoyan
  • 浏览: 9223241 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

在LINQ to SQL中处理“更新已被其它用户删除对象”的错误

阅读更多

在LINQ to SQL中处理“更新已被其它用户删除对象”的错误

在多用户条件下,当你正在修改一条记录时,很有可能另一个用户已把此记录删除。这时,等你修改完毕向数据库提交请求时,会出现“更新已被其它用户删除对象”的错误。

在LINQ to SQL中,所有本次数据更改冲突都被记录到DataContext.ChangeConflicts集合中。

通过遍历这个集合,可以知道引发冲突的原因。

多用户条件下引发数据更改冲突的原因主要有两种:

1更新已被其它用户更新的对象

2更新已被其它用户删除的对象

对于上述两种状况,LINQ to SQL采取了不同的处理方法。

对于第1种情况,LINQ to SQL的DataContext.ChangeConflicts集合对象提供了一个“ResolveAll(更新模式)”方法,最常用的是以下这个形式:

        //数据更新冲突时,将我的值与其他用户提交的值合并,但我修改过的值拥有最高优先级

context.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);

另两种更新冲突处理策略是:

(1) KeepCurrentValues即我的值最优先,不管我改过没有,一律用我的值覆盖对应的数据库值来解决此冲突。

(2)OverwriteCurrentValues 用数据库中的当前值全面取代我现在的值,放弃我做的修改。

选择好合适策略调用ResolveAll()后,再次调用DataContext.SubmitChanges()方法将会成功更新数据库。

对于第2种情况(“更新已被其它用户删除的对象”),LINQ to SQL的处理比较另类:

如果你调用ResolveAll(更新策略)方法,LINQ to SQL仅是简单地将与此对应的冲突对象(ObjectChangeConflict类型)的IsResolve属性设置为True,其结果是LINQ to SQL将不再尝试更新此对象!


换句话说:你调用ResolveAll(更新策略)方法后,LINQ to SQL认为你不打算处理这个已被其它用户删除的对象,就将其打入“冷宫”,不再理会。

现在有一个问题:

如果我想当“更新已被其它用户删除的对象”这一现象出现时,重新向数据库插入此对象,怎么办?

除非采用序列化方法,否则LINQ to SQL不允许将一个实体对象分离出来。但我们可以克隆一个新对象再将其插入到Table<entity>中。然后,将“更新已被其它用户删除的对象”对应的冲突对象设置为“已解决”状态。

以下代码片断来自于一个Windows Form应用程序:

     try
{
context.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException)
{
foreach (ObjectChangeConflict occ in context.ChangeConflicts)
{
//如果其它用户已删除此实体对象对应的数据库记录

if (occ.IsDeleted)
{

         //克隆一个新实体对象
Book newbook = CloneBook(book);
//下次提交时,将插入新对象到Book表中
context.Book.InsertOnSubmit(newbook);
//通知DataContext不再处理此已被其他用户删除数据库记录的实体对象
occ.Resolve();
}

}

//普通的更新冲突,则将我的值与其他用户提交的值合并以解决冲突

context.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
//再次提交
context.SubmitChanges(ConflictMode.FailOnFirstConflict);

}
catch (Exception ex)
{

MessageBox.Show(ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

上述模板代码中,context代表DataContext对象,Book是数据库中的表,LINQ to SQL会为它生成同名的实体类。

使用LINQ to SQL更新数据库需要有几个注意事项:

1 当数据表间有主键外键关联时,注意在数据库中将这个关联关系设置为层叠更新与删除。否则, SQL Server会阻止你删除主表记录。除非你一条条地将从表相关记录删除干净后才能删除主表记录。

对应地,如果你要删除某LINQ to SQL实体类对象,但这个对象还包容着相关联的子实体类对象时,一旦尝试向数据库提交更改,而数据库中没有将这个关联关系设置为层叠更新与删除,则LINQ to SQL将自动回滚操作,一条记录也删除不了!其原因是DataContext.SubmitChange()方法默认启动了一个事务,一出现异常则自动回滚。

2 克隆有主键外键关联的实体对象时,注意要一并克隆其所包容的子对象,而不要简单地赋值,那是“对象引用复制”而非“对象本身数据的复制”。具体来说,就是new一个新对象,然后逐个地把老对象的值赋给新对象,这个过程可能会递归好几层。最简单的方法是将原对象序列化到一个内存流中,然后从内存流中反序列化以实现对象的完全克隆。

3 如果需要获取数据库最新数据,可以调用DataContext.Refresh()方法,或者最简单的,直接向数据库发送一个新的LINQ查询,然后更新界面即可(推荐使用数据绑定),后面这个方法最简单可靠。

多用户环境下数据库的记录的存取冲突是一个令人头痛的问题,需要仔细地处理各种情况,这篇短文期望对大家有点帮助。

由于本人对LINQ to SQL技术研究与应用不深,因此,如本文有错,敬请朋友指出。

分享到:
评论

相关推荐

    Linq To Sql进阶系列

    - **Linq To Sql处理方法**:在Linq To Sql中,可以通过设置实体间的关联关系来自动处理多对多关系。当实体类间定义了正确的关联属性后,Linq To Sql会在后台自动创建必要的表结构和关联关系。 #### 3. Linq To Sql...

    linq to SQL

    在LINQ to SQL中,DataContext通常在DAL层中创建和使用,而实体类则作为数据传输对象(DTO)在各层之间传递。 总之,LINQ to SQL提供了一种高效且易于使用的数据访问机制,结合三层架构,可以构建出健壮且易于维护...

    LINQ(LINQ TO SQL)研究笔记

    2. **数据库连接**:在数据访问层中,利用LINQ to SQL,我们需要添加对`System.Linq`和`System.Linq.Mapping`的引用,以便使用LINQ的查询语法和数据模型映射特性。 3. **实体类定义**:为每个数据库表创建一个对应...

    LINQ to SQL中文资料

    3. **动态查询转换**:当应用程序运行时,**LINQ to SQL**会自动将对象模型中的查询转换为SQL语句,并发送到数据库执行;当数据库返回结果时,它又会将这些结果转换为对象,方便开发人员进一步处理。 #### 二、LINQ...

    优秀毕业设计(C#开发的基于LINQ TO SQL的三层架构)

    3. 数据访问层:该层负责与数据库的交互,通过LINQ TO SQL,可以轻松地创建、更新、删除和查询数据库记录。它隐藏了数据库操作的复杂性,为其他层提供了一个简单的接口。 在“精品课程网站”的优秀毕业设计中,...

    linq to sql

    - **类型安全**:使用LINQ to SQL编写的查询语句,在编译时就可以发现错误。 - **自动代码生成**:通过T4模板等工具可以自动生成数据上下文类和实体类,减少手动编码工作量。 - **性能优化**:提供了缓存机制和延迟...

    Linq to SQL使用介绍

    它提供了一种在 C# 或 VB.NET 等编程语言中直接操作数据库的方式,允许开发者用 LINQ(Language Integrated Query)语法对关系型数据库进行查询、插入、更新和删除操作。这种技术使得数据库访问更加简洁、类型安全,...

    一步一步学Linq to sql

    4. **插入、更新和删除操作**:Linq to SQL提供了简便的方法来执行CRUD(创建、读取、更新和删除)操作。只需更改对象的属性,然后调用DataContext的SubmitChanges()方法,即可将更改保存回数据库。 5. **处理关系*...

    linq to sql 初级教程

    - 在WPF和ASP.NET项目中,可以轻松地将数据绑定到控件,利用LINQ to SQL获取和展示数据。 10. **最佳实践** - 尽可能地复用DataContext实例,但避免跨线程使用。 - 对于大量数据操作,考虑批量插入和更新以减少...

    Linq to SQL入门代码

    在"Linq to SQL入门代码"中,我们可以看到如何利用这一技术实现基本的CRUD(创建、读取、更新、删除)操作以及分页功能。下面我们将详细探讨这些关键知识点: 1. **数据上下文(DataContext)**:这是Linq to SQL的...

    Linq to Sql 培训用的ppt与demo

    6. **数据修改操作**:了解如何使用Linq to Sql进行数据插入、更新和删除操作,包括添加新对象、更改对象状态和提交事务。 7. **延迟加载与即时加载**:理解延迟加载(Lazy Loading)和即时加载(Eager Loading)的...

    LINQ to SQL创建三层多层Web应用系统代码

    - **数据访问层**:通过LINQ to SQL,负责与数据库的通信,执行CRUD(创建、读取、更新、删除)操作。 3. **NORTHWIND数据库**:这是Microsoft提供的一款用于教学和测试的小型数据库,包含各种示例数据,如产品、...

    一步一步学LINQ to sql

    LINQ (Language Integrated Query) 是.NET框架中引入的一项强大功能,它允许程序员使用类似SQL的语法在各种数据源上执行查询。"LINQ to SQL"是LINQ的一个具体实现,专用于与关系数据库进行交互。这个教程将引领你...

    c#.net Linq to sql

    - 查询表达式:LINQ的核心是查询表达式,它们以类似于SQL的语法写在C#代码中,但被编译器转换为方法调用。 - LINQ提供者:不同的数据源需要不同的 LINQ 提供者来翻译查询表达式。例如,LINQ to SQL 将C#查询转换为...

    C#实现Siliverlight的LInq to sql的数据绑定

    一旦定义了这些实体类,我们就可以使用Linq to SQL的查询语法来执行CRUD(创建、读取、更新、删除)操作。 接下来,要实现Siliverlight中的数据绑定,我们需要以下几个步骤: 1. **创建数据模型**:在C#项目中定义...

    asp.net mvc linq to sql 增删改查 基本操作

    在ASP.NET MVC中使用Linq to SQL进行数据库操作,可以极大地提高开发效率和代码的可读性。以下是一些关于ASP.NET MVC结合Linq to SQL进行增删改查的基本操作的知识点: 1. **创建数据库上下文(DataContext)**:...

    基于.NET的LINQ to SQL三层架构的研究与实现.pdf

    文中首先介绍了LINQ作为一种数据操作技术,它能够将复杂查询简化为简单查询,解决了传统软件开发中冗余、复杂和难以实现的问题,并为开发者在处理代码业务逻辑编程方面提供了极大的便利。作为编程语言的一部分,LINQ...

Global site tag (gtag.js) - Google Analytics