2014-10-29 163 views
1

我目前使用实体框架并需要定期更新大量实体。SQL精简版批量更新

我需要做的是添加日志编号,它基于几个不同的表格。使用SQL Server,我可以使用一个存储过程,使用内部和外部连接,GROUP BY和ROW_NUMBER,这对我来说很繁重,而且效率也很高。

查看程序代码如下:在SQL CE不是可用

​​

由于存储过程,以及如何在子选择使用GROUP BY进一步的限制,我现在要计算日志数量在代码中。我在Context上使用SqlQuery来检索所需的最小数据集,对它进行分组,然后开始每个实体的更新。

SELECT ZID 
FROM 
    (SELECT S.Id as [SID], Z.Id as [ZID], B.Id as [BID], S.TicksCreatedOn 
    FROM ChildTable AS B 
     INNER JOIN TableWithNumber as Z on Z.ChildTableRefA_Id = B.Id 
     INNER JOIN ParentTable as S on Z.ParentTable_Id = S.Id 
    WHERE S.Ref_Id = @RefId 
    UNION 
    SELECT S.Id as [SID], Z.Id as [ZID], B.Id as [BID], S.TicksCreatedOn 
    FROM ChildTable AS B 
     INNER JOIN TableWithNumber as Z on Z.ChildTableRefB_Id = B.Id 
     INNER JOIN ParentTable as S on Z.ParentTable_Id = S.Id 
     WHERE S.Ref_Id = @RefId) AS D 
ORDER BY TicksCreatedOn, ZID, BID 


     var result = Database.SqlQuery<NumberUpdate>(QUERY, new SqlCeParameter("@RefId", 1)).ToList(); 

上的应用程序的代码看起来有点像这样

var grouped = result 
     .Select((x,y) => new NumberUpdate { ZID = x.ZID, Number = ++y }) 
     .GroupBy(x => x.ZID); 

    foreach (var group in grouped) 
    { 
     Database.ExecuteSqlCommand("UPDATE TableWithNumber SET Number = @Nr WHERE Id = @Id", 
      new SqlCeParameter("@Nr", group.Min(x => x.Number)), 
      new SqlCeParameter("@Id", group.Key)); 
    } 

我想知道如果有一个更快或更有效的方式来更新SQL CE实体的名单比在foreach调用ExecuteSqlCommand循环?

+0

我能找到的唯一改进是在'foreach'循环之前准备好SqlCeCommand,然后在循环中只改变现有参数的值。但是SQL CE中的UPDATE非常有限。 – 2014-10-29 14:59:13

+0

如果您需要嵌入式数据库中的存储过程和触发器,请考虑[LocalDB](http://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql- express.aspx)。 – 2014-10-29 16:43:56

+0

LocalDB本来就非常棒,并会喜欢使用它。但是,我们的应用程序的一个关键要求是,它应该是可部署的复制/过去,并且不需要安装例程。由于LocalDB需要在客户端进行设置,因此不幸的是这不是一个选项。再一次,我会很乐意使用它。 – UrbanEsc 2014-10-29 20:19:48

回答

0

如果您的业务逻辑允许您“逐行”更新多个表中的数据(而不是使用复杂的SQL命令),那么您可以尝试“table-direct”方法。它涉及以下步骤。

创建SqlCeConnection连接字符串指向您的SDF文件的对象。创建SqlCeCommand此命令类型的连接的对象CommandType.TableDirect。创建SqlCeResultSet带选项ResultSetOptions.UpdatableResultSetOptions.Scrollable

现在你可以使用寻求更新方法来更新表行。这种方法可能是最快的方法。但是它需要比传统的EF方法编写更多的代码。