从 XML C# 中取出项目并执行批量删除
Taking out items from XML C# and performing bulk delete
我有一段代码如下所示:
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\DeletedItems\" + "DeletedItems" + ".xml";
XDocument xmlDoc = XDocument.Load(filePath);
var list = xmlDoc.Root.Elements("ItemID")
.Select(element => element.Value)
.ToList();
var idsList = FormItemIdList(list);
ctx.zsp_deleteEndedItems(idsList);
ctx.zsp_deleteEndedItemsTransactions(idsList);
这部分代码加载 XML 文件中的所有项目:
var list = xmlDoc.Root.Elements("ItemID")
.Select(element => element.Value)
.ToList();
XML 文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<ItemsToDelete>
<ItemID>113347292264</ItemID>
<ItemID>113334066205</ItemID>
<ItemID>113331816848</ItemID>
<ItemID>113191634415</ItemID>
<ItemID>183480362055</ItemID>
<ItemID>113303425739</ItemID>
<ItemID>112533425202</ItemID>
<ItemID>112007496785</ItemID>
<ItemID>111956371906</ItemID>
<ItemID>112016647700</ItemID>
</ItemsToDelete>
一旦项目从 C# 加载到列表中,我就会形成一个如下所示的字符串:
113347292264,113334066205... etc etc
然后将字符串传递给如下所示的存储过程:
create procedure [dbo].[zsp_deleteEndedItems]
(
@ItemIDList nvarchar(max)
)
as
delete from
SearchedUserItems
WHERE EXISTS (SELECT 1 FROM dbo.SplitStringProduction(@ItemIDList,',') S1 WHERE ItemID=S1.val)
然后调用SplitStringProduction函数分解传入的字符串,根据传入的item ID删除DB中的记录:
create FUNCTION [dbo].[SplitStringProduction]
(
@string nvarchar(max),
@delimiter nvarchar(5)
) RETURNS @t TABLE
(
val nvarchar(500)
)
AS
BEGIN
declare @xml xml
set @xml = N'<root><r>' + replace(@string,@delimiter,'</r><r>') + '</r></root>'
insert into @t(val)
select
r.value('.','varchar(500)') as item
from @xml.nodes('//root/r') as records(r)
RETURN
END
现在,所有这些工作正常,但有一些我知道并希望避免的问题:
- XML 文件中的列表可能很长,通常包含 100000 多条记录
现在为了避免这种情况,我正在考虑执行以下操作:
- 假设批量删除5000条记录
所以步骤是:
- 从 XML 文件中提取 5000 个项目
- 将这 5000 个项目传递到过程中
- 从 XML 文件中删除 5000 个 ItemID
谁能帮我解决这个问题,我不知道该怎么做?
听起来您只想将列表分成更小的块:
var list = xmlDoc.Root.Elements("ItemID")
.Select(element => element.Value)
.ToList();
while(list.Any())
{
var subList = list.Take(5000);
var idsList = FormItemIdList(subList);
ctx.zsp_deleteEndedItems(idsList);
ctx.zsp_deleteEndedItemsTransactions(idsList);
list.RemoveRange(subList);
}
我有一段代码如下所示:
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\DeletedItems\" + "DeletedItems" + ".xml";
XDocument xmlDoc = XDocument.Load(filePath);
var list = xmlDoc.Root.Elements("ItemID")
.Select(element => element.Value)
.ToList();
var idsList = FormItemIdList(list);
ctx.zsp_deleteEndedItems(idsList);
ctx.zsp_deleteEndedItemsTransactions(idsList);
这部分代码加载 XML 文件中的所有项目:
var list = xmlDoc.Root.Elements("ItemID")
.Select(element => element.Value)
.ToList();
XML 文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<ItemsToDelete>
<ItemID>113347292264</ItemID>
<ItemID>113334066205</ItemID>
<ItemID>113331816848</ItemID>
<ItemID>113191634415</ItemID>
<ItemID>183480362055</ItemID>
<ItemID>113303425739</ItemID>
<ItemID>112533425202</ItemID>
<ItemID>112007496785</ItemID>
<ItemID>111956371906</ItemID>
<ItemID>112016647700</ItemID>
</ItemsToDelete>
一旦项目从 C# 加载到列表中,我就会形成一个如下所示的字符串:
113347292264,113334066205... etc etc
然后将字符串传递给如下所示的存储过程:
create procedure [dbo].[zsp_deleteEndedItems]
(
@ItemIDList nvarchar(max)
)
as
delete from
SearchedUserItems
WHERE EXISTS (SELECT 1 FROM dbo.SplitStringProduction(@ItemIDList,',') S1 WHERE ItemID=S1.val)
然后调用SplitStringProduction函数分解传入的字符串,根据传入的item ID删除DB中的记录:
create FUNCTION [dbo].[SplitStringProduction]
(
@string nvarchar(max),
@delimiter nvarchar(5)
) RETURNS @t TABLE
(
val nvarchar(500)
)
AS
BEGIN
declare @xml xml
set @xml = N'<root><r>' + replace(@string,@delimiter,'</r><r>') + '</r></root>'
insert into @t(val)
select
r.value('.','varchar(500)') as item
from @xml.nodes('//root/r') as records(r)
RETURN
END
现在,所有这些工作正常,但有一些我知道并希望避免的问题:
- XML 文件中的列表可能很长,通常包含 100000 多条记录
现在为了避免这种情况,我正在考虑执行以下操作:
- 假设批量删除5000条记录
所以步骤是:
- 从 XML 文件中提取 5000 个项目
- 将这 5000 个项目传递到过程中
- 从 XML 文件中删除 5000 个 ItemID
谁能帮我解决这个问题,我不知道该怎么做?
听起来您只想将列表分成更小的块:
var list = xmlDoc.Root.Elements("ItemID")
.Select(element => element.Value)
.ToList();
while(list.Any())
{
var subList = list.Take(5000);
var idsList = FormItemIdList(subList);
ctx.zsp_deleteEndedItems(idsList);
ctx.zsp_deleteEndedItemsTransactions(idsList);
list.RemoveRange(subList);
}