我正在使用linq从数据库中的表中检索一行。 现在我只更新1列。 然后我将其更新回数据库。
这很顺利,除了其他进程/线程/用户更改任何其他字段的时间 在那种情况下,我得到一个异常(乐观并发),告诉我注意,自从我上次使用linq获取对象后,值已经改变。
由于我只对这一列感兴趣,我可以告诉linq只更新此列并忽略其他列吗? (并警告我这一栏确实已经改变了)
[R
答案 0 :(得分:4)
您可以通过捕获ChangeConflictException:
来检测并解决并发问题using (var db = new MyDataContext())
{
var row = db.MyTable.Single(x => x.Id == tableId); // Getting the row
row.Column = columnNewValue; // Assign the new value
try
{
db.SubmitChanges();
}
catch (ChangeConflictException)
{
db.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
db.SubmitChanges();
}
}
使用RefreshMode。KeepChanges对客户端对象所做的所有更改都将保留,其他列上的其他用户/进程/线程的更改将合并。
在您的情况下,只会更改您的列。
推荐文章:
答案 1 :(得分:1)
我不太清楚这一点,但看起来你可以使用ColumnAttribute上的UpdateCheck.Never枚举值来完全避免并发检查。
答案 2 :(得分:1)
MSDN中有一篇很好的文章:
以下示例(文章中的稍后一点)可能特别重要:
public partial class Northwind : DataContext
{
...
public void UpdateProduct(Product original, Product current) {
// Execute the stored procedure for UnitsInStock update
if (original.UnitsInStock != current.UnitsInStock) {
int rowCount = this.ExecuteCommand(
"exec UpdateProductStock " +
"@id={0}, @originalUnits={1}, @decrement={2}",
original.ProductID,
original.UnitsInStock,
(original.UnitsInStock - current.UnitsInStock)
);
if (rowCount < 1)
throw new Exception("Error updating");
}
...
}
}
您的存储过程是:
create proc UpdateProductStock
@id int,
@originalUnits int,
@decrement int
as
UPDATE Product
SET originalUnits=@originalUnits,
decrement=@decrement
WHERE id=@id
根据我的经验,最好的方法是制作自己的存储过程。 Linq不提供一种简单的方法来同时进行更改,除非您将(几乎)所有列的“UpdateCheck”属性设置为“Never”。
答案 3 :(得分:0)
听起来你可能正在以单例模式使用DataContext,或者至少在多个线程中共享它。
当您在DataContext上调用SubmitChanges时,将执行DataContext知道的所有数据库更改。
DataContext仅用作工作单元对象,并在您完成该工作后立即处理。
答案 4 :(得分:0)
我找到了 this 。那是你要找的吗?
如果这不能解决问题,您可以随时构建 sql update statement 并执行它。
答案 5 :(得分:0)
您可以执行此操作,但这需要您以某种方式构建代码。
例如,您有一个需要单独更新的说明和金额。然后,您将创建2个方法:
然后在例如更新的数量方法:
当你这样做时,你只会改变你想要改变的东西。
我们使用此模式的时间是由于审核要求。您可以说此用户更改了金额,此用户更改了说明。并非每个用户都更改了记录,您需要查看数据以查看他们的操作。
答案 6 :(得分:0)
我读了一篇文章,讨论在运行时更改UpdateCheck属性的可能性。 (根据'我可能需要某一天'类别提交它,但到目前为止我还没需要它。)
见
http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2007/12/20/10038.aspx
答案 7 :(得分:0)
如果您有权更改数据库架构,请将时间戳列添加到相关数据表中,然后确保没有为并发更新设置其他列(它应自动获取TimeStamp列,但可能需要如果没有,则重新生成dbml中的表。当你有一个TimeStamp列时,LINQ to SQL只会在进行并发检查时使用该字段,从而允许更加离散的更新。
答案 8 :(得分:0)
使用http://plinqo.com处的PLINQO框架,如果您喜欢使用属于PLINQO的批处理操作,则可以更新一列。
context.Task.Update(t =&gt; t.Id == 1,t2 =&gt; new Task {StatusId = 2});
这将执行更新任务集StatusId = 2其中Id = 1