我使用vb.net实体访问sql server 2014数据库中的数据。
我有一个接收"所有者的功能"对象,如果所有者在表中有多个当前条目,则它应该更新旧条目以具有先前的状态。
Private Shared Sub CreatePreviousOwners(currentOwners As List(Of Owner), prop As compProp)
Dim names = prop.GetVendorsNames()
Using context = New GovernContext()
Dim sameOwners = From v In currentOwners
Where names.Any(Function(o) o.Na_Id = v.Na_Id)
Select v
If sameOwners.Count > 0 Then
For Each owner In sameOwners
'Find all entries prior to the newest
Dim prevOwner = From p In context.Owner
Where p.Status = "O" _
And owner.Na_Id = p.Na_Id _
And p.P_Id = prop.p_id _
And p.As_Of_Date < owner.As_Of_Date
Select p
'Update all found entries to previous
For Each own As Owner In prevOwner
own.Status = "P"
Next
Next
context.SaveChanges()
End If
End Using
End Sub
这是一个小数据集:
p_id na_id AS_OF_DATE status
596 589494 2008-09-10 00:00:00.000 O
596 589494 2017-08-02 00:00:00.000 O
596 1453364 2017-08-02 00:00:00.000 P
当我单步执行代码时,prevOwner序列中只有一个条目。
当我运行sql探查器来查看linq查询时,update语句缺少任何as_of_date条件。 这是来自探查者的查询:
exec sp_executesql N'UPDATE [dbo].[Owner]
SET [Status] = @0
WHERE (([P_Id] = @1) AND ([Na_Id] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 int',@0=N'P',@1=596,@2=589494
我的sql是否格式错误,或者我遗失了什么?
答案 0 :(得分:2)
您似乎对实体框架抱有太多期待。当EF更新数据库记录时,它总是一次一条记录。它不进行批量更新。
以下是您的代码中发生的情况(我稍作修改):
Private Shared Sub CreatePreviousOwners(currentOwners As List(Of Owner), prop As compProp)
Dim names = prop.GetVendorsNames()
Using context = New GovernContext()
'Runs a SQL SELECT query and creates a list of owners
Dim sameOwners = (From v In currentOwners
Where names.Any(Function(o) o.Na_Id = v.Na_Id)
Select v).ToList()
For Each owner In sameOwners
'Find all entries prior to the newest
'Runs another SQL SELECT query
Dim prevOwner = From p In context.Owner
Where p.Status = "O" _
And owner.Na_Id = p.Na_Id _
And p.P_Id = prop.p_id _
And p.As_Of_Date < owner.As_Of_Date
Select p
'Update all found entries to previous
'Executes the SELECT query and loops through the results
For Each own As Owner In prevOwner
'Adds a modified entry to EF's change tracker
own.Status = "P"
Next
Next
'Runs update statements for each modified entry in the change tracker
context.SaveChanges()
End Using
End Sub
如您所见,在EF准备更新数据库时,它不知道如何收集修改后的条目。更新可以更加智能,即在更新满足条件Owner
的批量p.As_Of_Date < owner.As_Of_Date
的语句中,但收集数据和更新它们是EF中完全独立的操作。
这就是为什么你只看到UPDATE语句,其中一个记录由其主键标识。你可能会看到很多。
有第三方库可以批量(或批量)更新,插入和删除。