gpt4 book ai didi

WCF Entity Framework 并发

转载 作者:行者123 更新时间:2023-12-05 00:39:42 24 4
gpt4 key购买 nike

我有一个 WCF 服务,它调用我的 Entity Framework 存储库类来访问数据。我使用 Entity Framework 4 CTP,并且使用我自己的 POCO 对象而不是自动生成的实体对象。

上下文生命周期仅限于方法调用。对于 Select/Insert 和 Update 方法,我创建上下文并在返回断开连接的实体对象的相同方法中处理它。

我现在正在尝试找出处理并发问题的最佳方法。例如,这就是我的更新方法的样子

public static Sale Update(Sale sale)
{
using (var ctx = new DBContext())
{
var SaleToUpdate =
(from t in ctx.Sales where t.ID == sale.ID select t).FirstOrDefault();
if (SaleToUpdate == null) throw new EntityNotFoundException();
ctx.Sales.ApplyCurrentValues(sale);
ctx.SaveChanges();
return sale;
}
}

这工作正常,但因为我以断开连接的方式工作,如果自您拿起记录以来已修改记录,则不会引发异常。这将导致并发问题。

当您在 WCF 上使用 Entity Framework 并且没有保持全局上下文时,解决此问题的最佳方法是什么?

我能想到的唯一方法是给我的对象一个版本号,并在每次调用保存时增加它。这将允许我在保存之前检查版本没有改变。不是我所知道的最简洁的解决方案,并且仍然允许客户更改他们的版本号,我真的不希望他们能够这样做。

编辑:
使用 Ladislav Mrnka 对实体中 RowVersion 字段的建议,我的每个实体现在都有一个名为 Version 类型的 RowVersion 字段。然后我将我的 Update 方法更改为如下所示。
public static Sale Update(Sale sale)
{
using (var ctx = new DBContext())
{
var SaleToUpdate =
(from t in ctx.Sales where t.ID == sale.ID select t).FirstOrDefault();
if (SaleToUpdate == null) throw new EntityNotFoundException();
if (!sale.Version.SequenceEqual(SaleToUpdate .Version))
throw new OptimisticConcurrencyException("Record is out of date");
ctx.Sales.ApplyCurrentValues(sale);
ctx.SaveChanges();
return sale;
}
}

它似乎有效,但如果我应该以不同的方式做,请告诉我。我尝试通过将版本字段并发模式设置为固定来使用内置于并发控制的 Entity Framework ,不幸的是,这不起作用,因为当我执行查询以获取未更改的 SaleToUpdate 时,它​​选择了它的版本并用它来进行并发检查这显然是当前的。感觉 Entity Framework 可能在这里遗漏了一些东西。

最佳答案

不要使用自定义版本号。使用数据库的内置行版本数据类型。每次更改记录时,都会自动修改行版本数据类型。例如 MSSQL 具有时间戳数据类型。您可以使用 EF 中的时间戳列并将其设置为固定并发处理程序(不确定如何使用 EF Code First 来实现,但我相信 fluent API 具有这种可能性)。时间戳列必须作为字节数组(8 个字节)映射到 POCO 实体。当您调用更新方法时,您可以自己检查已加载对象的时间戳和传入对象的时间戳,以避免不必要地调用 DB。如果您不自己进行检查,它将通过在更新语句中设置 where 条件在 EF 中处理。

关于WCF Entity Framework 并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4366571/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com