问题1:在多用户环境中,我们应该使用Entity Framework来实现对表格进行多次更新(100行)的功能吗?
问题2:在以下情况下,我们是否做出了正确的决策来使用EF?
场景:库存计数网页包含一个可编辑的网格视图控件,允许用户每次更新100行。
背景:库存计数用于记录期末库存数量。所有组织的期末关闭时间均为星期一。大约有10个正在使用的组织,每个组织平均至少有100个以上的站点在同一时间进行库存关闭。
基于ADO.NET的类似屏幕运作良好。但是团队正在尝试在新屏幕上引入Entity Framework。我们进行了方法级压力测试,并没有得到令人满意的EF结果。我们运行了测试2分钟,并模拟了从5个用户到35个用户的负载。
以下是结果:
ADO.NET 使用存储过程逐一进行一次数据库更新。
5 Users - Number of test per second per user - 80
35 Users - Number of test per second per user - 150
EF使用SaveChanges()方法,该方法逐一更新数据库。
5 Users - Number of test per second per user - 43
35 Users - Number of test per second per user - 43
EF代码:
方法1
context.Configuration.AutoDetectChangesEnabled = false;
context.Set<LocationData>().AddRange(data); //data is a collection of LocationData
foreach (var locationData in data)
{
var entry = context.Entry(locationData);
entry.State = EntityState.Modified;
}
context.SaveChanges();
方法1的代码分析器详细信息
方法2
context.Configuration.AutoDetectChangesEnabled = false;
foreach (var locationData in data)
{
context.Set<LocationData>().Attach(data);
var entry = context.Entry(locationData);
entry.State = EntityState.Modified;
}
context.SaveChanges();
第二种方法的代码分析器细节
由Entity Framework生成的SQL查询
exec sp_executesql N'
UPDATE [dbo].[LocationData]
SET [LocationId] = @0, [ClientId] = @1, [ProductId] = @2,
[SupplierProductId] = @3, [MenuId] = @4, [MenuNumber] = @5, [CaskNumber] = @6
WHERE ([Id] = @7)',N'@0 bigint,@1 bigint,@2 bigint,@3 bigint,@4 bigint, @5 bigint,@6 nvarchar(64),@7 bigint',
@0=22371851,@1=22371851,@2=22371851,@3=22371851,@4=22371851,@5=22371851,@6=N'Cask0091',@7=22371851
由ADO.NET生成的SQL查询
Update LocationData
set
LocationId = @LocationId,
ClientId= @ClientID,
ProductId= @ProductId,
SupplierProductId=@SupplierProductId, MenuId= @MenuId,
MenuNumber= @MenuNumber,
CaskNumber= @CaskNumber
WHERE LocationData.Id = @Id
这些测试并没有在事务下执行。
我在开发过程中使用了以下工具:Visual Studio 2012 Ultimate、Sql Server R2、Entity Framework 6.0.2、.NET 4.5和C#。