【发布时间】:2014-05-28 00:07:10
【问题描述】:
我正在开发一个使用实体框架的 asp.net mvc Web 应用程序。我的 asp.net mvc Web 应用程序中有以下模型类:-
public partial class TMSSwitchPort
{
public int TechnologyID { get; set; }
public int SwitchID { get; set; }
public string PortNumber { get; set; }
public virtual Technology Technology { get; set; }
public virtual TMSSwitch TMSSwitch { get; set; }
}
我有以下存储库方法:-
public void changeDeviceSwitch(int fromID , int toID)
{
var currentdevices = tms.TMSSwitchPorts.Where(a => a.SwitchID == fromID);
foreach (var d in currentdevices)
{
tms.TMSSwitchPorts.Remove(d);
}
foreach (var d in currentdevices)
{
TMSSwitchPort tsp = new TMSSwitchPort() { SwitchID = toID,
TechnologyID = d.TechnologyID, PortNumber = d.PortNumber };
tms.TMSSwitchPorts.Add(d);
}
tms.SaveChanges();
}
上述方法主要会检索所有具有特定 switchID 的对象,将其删除,并添加具有新 switchID 的新记录。 目前我正在尝试了解并发用户同时执行该方法时会发生什么。从我的测试中,我发现第一个用户将能够删除和添加新记录,而其他用户将获得 DbUpdateConcurrencyException。 因此,据我了解,我观察到以下情况,假设 UserA 和 UserB 同时访问相同的方法:-
UserA 检索所有当前设备。
UserB 同时检索所有当前设备。
UserA 将所有对象标记为删除,创建新对象,Save()。
UserB 将所有对象标记为删除,创建新对象,
现在当 userB 到达 Save() 时,EF 会发现有一些对象(或所有对象)已被标记为删除但不再存在(因为它们已被 UserA 删除),并且它将引发 DbUpdateConcurrencyException。
所以这意味着 EF 在尝试删除不再存在的对象时会引发 DbUpdateConcurrencyException,即使我没有使用时间戳也是如此。我检查了 sql profiler,为删除操作生成的 sql 语句如下所示:-
exec sp_executesql N'delete [dbo].[TMSSwitchPorts]
where (([SwitchID] = @0) and ([PortNumber] = @1))',N'@0 int,@1 nvarchar(10)',@0=467,@1=N'a'
那么我对 EF 对上述代码的反应方式的理解是否正确?
【问题讨论】:
标签: asp.net-mvc entity-framework concurrency sql-server-2008-r2 asp.net-mvc-5