Vac*_*ano 10 sql-server parameters dapper
我正在尝试使用Dapper支持我的服务器应用程序的数据访问.
我的服务器应用程序有另一个应用程序,它以每分钟400的速度将记录丢入我的数据库.
我的应用程序将它们分批拉出,处理它们,然后从数据库中删除它们.
由于数据在我处理时继续流入数据库,因此我没有好的方法可以说delete from myTable where allProcessed = true.
但是,我确实知道要删除的行的PK值.所以我想做一个delete from myTable where Id in @listToDelete
问题是,如果我的服务器停机甚至6分钟,那么我有超过2100行要删除.
由于Dapper接受我的@listToDelete并将每个变成一个参数,我对delete的调用失败了.(导致我的数据清除进一步落后.)
在Dapper处理这个问题的最佳方法是什么?
注意:我已经查看了Tabled Valued Parameters,但从我所看到的情况来看,它们并不是非常高效.这段我的建筑是我系统的瓶颈,我需要非常快.
Chr*_*ith 14
一种选择是在服务器上创建临时表,然后使用批量加载工具立即将所有ID上载到该表中.然后使用join,EXISTS或IN子句仅删除上载到临时表中的记录.
批量加载是SQL Server中一个优化良好的路径,它应该非常快.
例如:
CREATE TABLE #RowsToDelete(ID INT PRIMARY KEY)#RowsToDeleteDELETE FROM myTable where Id IN (SELECT ID FROM #RowsToDelete)DROP TABLE #RowsToDelte(如果关闭会话,表也将自动删除)(假设Dapper)代码示例:
conn.Open();
var columnName = "ID";
conn.Execute(string.Format("CREATE TABLE #{0}s({0} INT PRIMARY KEY)", columnName));
using (var bulkCopy = new SqlBulkCopy(conn))
{
bulkCopy.BatchSize = ids.Count;
bulkCopy.DestinationTableName = string.Format("#{0}s", columnName);
var table = new DataTable();
table.Columns.Add(columnName, typeof (int));
bulkCopy.ColumnMappings.Add(columnName, columnName);
foreach (var id in ids)
{
table.Rows.Add(id);
}
bulkCopy.WriteToServer(table);
}
//or do other things with your table instead of deleting here
conn.Execute(string.Format(@"DELETE FROM myTable where Id IN
(SELECT {0} FROM #{0}s", columnName));
conn.Execute(string.Format("DROP TABLE #{0}s", columnName));
Run Code Online (Sandbox Code Playgroud)
为了让这段代码正常工作,我走到了黑暗的一边.
由于Dapper使我的列表成为参数.而SQL Server无法处理很多参数.(我以前从未需要双位数参数).我不得不使用Dynamic SQL.
所以这是我的解决方案:
string listOfIdsJoined = "("+String.Join(",", listOfIds.ToArray())+")";
connection.Execute("delete from myTable where Id in " + listOfIdsJoined);
Run Code Online (Sandbox Code Playgroud)
在每个人抓住他们的火把和干草叉之前,让我解释一下.
我知道构建动态SQL是坏juju,但在这种情况下,我只是看不出它如何导致安全风险.
| 归档时间: |
|
| 查看次数: |
10139 次 |
| 最近记录: |