如何批量删除两个日期之间的记录?
How to delete records between two dates in bulk?
我想删除两个日期之间的记录。我使用 Fetchxml 表达式获取两个日期之间每条记录的 GUID,然后我使用 service.Delete
。这是我的代码:
string fetchXml = @" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='new_units'>
<link-entity name='new_alterunitorder' from ='new_orderlineid' to = 'new_unitsid' >
<attribute name='new_alterunitorderid' />
<filter type='and'>
<condition attribute='new_orderdate' operator='on-or-after' value='" + startDate.ToShortDateString() + @"' />
<condition attribute='new_orderdate' operator='on-or-before' value='" + endDate.ToShortDateString() + @"' />
<condition attribute='new_orderlineid' operator='eq' uiname='" + uiName + @"' uitype='new_units' value='" + unitOrderId + @"' />
</filter>
</link-entity>
</entity>
</fetch>";
EntityCollection result = service.RetrieveMultiple(new FetchExpression(fetchXml));
//Delete the collection
foreach (var id in result.Entities)
{
var entRef = id.GetAttributeValue<EntityReference>("new_alterunitorderid");
var guid = (Guid)entRef.Id;
service.Delete("new_alterunits", guid);
}
FetchXML 有 5000 条记录的限制,我该如何绕过它?!我还读到循环使用 service.Delete
不是推荐的批量删除方式。请帮助我找到实现我想做的事情的最佳方法!
FetchXML has a limitation of 5000 records, how can I bypass that?
答案是Paging cookie。
可以使用 ExecuteMultipleRequest
进行批量删除。
public static void BulkDelete(IOrganizationService service, DataCollection<EntityReference> entityReferences)
{
// Create an ExecuteMultipleRequest object.
var multipleRequest = new ExecuteMultipleRequest()
{
// Assign settings that define execution behavior: continue on error, return responses.
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = true
},
// Create an empty organization request collection.
Requests = new OrganizationRequestCollection()
};
// Add a DeleteRequest for each entity to the request collection.
foreach (var entityRef in entityReferences)
{
DeleteRequest deleteRequest = new DeleteRequest { Target = entityRef };
multipleRequest.Requests.Add(deleteRequest);
}
// Execute all the requests in the request collection using a single web method call.
ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
}
您可能还想研究通过 BulkDeleteRequest class 使用本机批量删除服务。
下面是一个基本的例子,this article has a more detailed example. If you want to convert your FetchXML to a QueryExpression, you can use the FetchXmlToQueryExpressionRequestclass。
// Set the request properties.
bulkDeleteRequest.JobName = "Backup Bulk Delete";
// Querying activities
bulkDeleteRequest.QuerySet = new QueryExpression[]
{
opportunitiesQuery,
BuildActivityQuery(Task.EntityLogicalName),
BuildActivityQuery(Fax.EntityLogicalName),
BuildActivityQuery(PhoneCall.EntityLogicalName),
BuildActivityQuery(Email.EntityLogicalName),
BuildActivityQuery(Letter.EntityLogicalName),
BuildActivityQuery(Appointment.EntityLogicalName),
BuildActivityQuery(ServiceAppointment.EntityLogicalName),
BuildActivityQuery(CampaignResponse.EntityLogicalName),
BuildActivityQuery(RecurringAppointmentMaster.EntityLogicalName)
};
// Set the start time for the bulk delete.
bulkDeleteRequest.StartDateTime = DateTime.Now;
// Set the required recurrence pattern.
bulkDeleteRequest.RecurrencePattern = String.Empty;
// Set email activity properties.
bulkDeleteRequest.SendEmailNotification = false;
bulkDeleteRequest.ToRecipients = new Guid[] { currentUserId };
bulkDeleteRequest.CCRecipients = new Guid[] { };
// Submit the bulk delete job.
// NOTE: Because this is an asynchronous operation, the response will be immediate.
_bulkDeleteResponse =
(BulkDeleteResponse)_serviceProxy.Execute(bulkDeleteRequest);
Console.WriteLine("The bulk delete operation has been requested.");
现在我们已经明确了要求,下面是我将如何解决这个问题的要点。它使用简化的 FetchXML 查询,但您会明白的。
请注意在 Fetch 中添加了 top='2000'
。
var fetchXml = @" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false' top='2000'>
<entity name='new_sampledata' />
</fetch>";
var result = svc.RetrieveMultiple(new FetchExpression(fetchXml));
var entityRefs = result.Entities.Select(e=> e.ToEntityReference());
//instead of e.ToEntityReference(), you'd use e.GetAttributeValue<EntityReference>("new_alterunitorderid")
//like this:
//var entityRefs = result.Entities.Select(e=> e.GetAttributeValue<EntityReference>("new_alterunitorderid"));
var batchSize = 1000;
var batchNum = 0;
var numDeleted = 0;
while (numDeleted < entityRefs.Count())
{
var multiReq = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = false
},
Requests = new OrganizationRequestCollection()
};
var currentList = entityRefs.Skip(batchSize * batchNum).Take(batchSize).ToList();
currentList.ForEach(r => multiReq.Requests.Add(new DeleteRequest { Target = r }));
svc.Execute(multiReq);
numDeleted += currentList.Count;
batchNum++;
}
我想删除两个日期之间的记录。我使用 Fetchxml 表达式获取两个日期之间每条记录的 GUID,然后我使用 service.Delete
。这是我的代码:
string fetchXml = @" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='new_units'>
<link-entity name='new_alterunitorder' from ='new_orderlineid' to = 'new_unitsid' >
<attribute name='new_alterunitorderid' />
<filter type='and'>
<condition attribute='new_orderdate' operator='on-or-after' value='" + startDate.ToShortDateString() + @"' />
<condition attribute='new_orderdate' operator='on-or-before' value='" + endDate.ToShortDateString() + @"' />
<condition attribute='new_orderlineid' operator='eq' uiname='" + uiName + @"' uitype='new_units' value='" + unitOrderId + @"' />
</filter>
</link-entity>
</entity>
</fetch>";
EntityCollection result = service.RetrieveMultiple(new FetchExpression(fetchXml));
//Delete the collection
foreach (var id in result.Entities)
{
var entRef = id.GetAttributeValue<EntityReference>("new_alterunitorderid");
var guid = (Guid)entRef.Id;
service.Delete("new_alterunits", guid);
}
FetchXML 有 5000 条记录的限制,我该如何绕过它?!我还读到循环使用 service.Delete
不是推荐的批量删除方式。请帮助我找到实现我想做的事情的最佳方法!
FetchXML has a limitation of 5000 records, how can I bypass that?
答案是Paging cookie。
可以使用 ExecuteMultipleRequest
进行批量删除。
public static void BulkDelete(IOrganizationService service, DataCollection<EntityReference> entityReferences)
{
// Create an ExecuteMultipleRequest object.
var multipleRequest = new ExecuteMultipleRequest()
{
// Assign settings that define execution behavior: continue on error, return responses.
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = true
},
// Create an empty organization request collection.
Requests = new OrganizationRequestCollection()
};
// Add a DeleteRequest for each entity to the request collection.
foreach (var entityRef in entityReferences)
{
DeleteRequest deleteRequest = new DeleteRequest { Target = entityRef };
multipleRequest.Requests.Add(deleteRequest);
}
// Execute all the requests in the request collection using a single web method call.
ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
}
您可能还想研究通过 BulkDeleteRequest class 使用本机批量删除服务。
下面是一个基本的例子,this article has a more detailed example. If you want to convert your FetchXML to a QueryExpression, you can use the FetchXmlToQueryExpressionRequestclass。
// Set the request properties.
bulkDeleteRequest.JobName = "Backup Bulk Delete";
// Querying activities
bulkDeleteRequest.QuerySet = new QueryExpression[]
{
opportunitiesQuery,
BuildActivityQuery(Task.EntityLogicalName),
BuildActivityQuery(Fax.EntityLogicalName),
BuildActivityQuery(PhoneCall.EntityLogicalName),
BuildActivityQuery(Email.EntityLogicalName),
BuildActivityQuery(Letter.EntityLogicalName),
BuildActivityQuery(Appointment.EntityLogicalName),
BuildActivityQuery(ServiceAppointment.EntityLogicalName),
BuildActivityQuery(CampaignResponse.EntityLogicalName),
BuildActivityQuery(RecurringAppointmentMaster.EntityLogicalName)
};
// Set the start time for the bulk delete.
bulkDeleteRequest.StartDateTime = DateTime.Now;
// Set the required recurrence pattern.
bulkDeleteRequest.RecurrencePattern = String.Empty;
// Set email activity properties.
bulkDeleteRequest.SendEmailNotification = false;
bulkDeleteRequest.ToRecipients = new Guid[] { currentUserId };
bulkDeleteRequest.CCRecipients = new Guid[] { };
// Submit the bulk delete job.
// NOTE: Because this is an asynchronous operation, the response will be immediate.
_bulkDeleteResponse =
(BulkDeleteResponse)_serviceProxy.Execute(bulkDeleteRequest);
Console.WriteLine("The bulk delete operation has been requested.");
现在我们已经明确了要求,下面是我将如何解决这个问题的要点。它使用简化的 FetchXML 查询,但您会明白的。
请注意在 Fetch 中添加了 top='2000'
。
var fetchXml = @" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false' top='2000'>
<entity name='new_sampledata' />
</fetch>";
var result = svc.RetrieveMultiple(new FetchExpression(fetchXml));
var entityRefs = result.Entities.Select(e=> e.ToEntityReference());
//instead of e.ToEntityReference(), you'd use e.GetAttributeValue<EntityReference>("new_alterunitorderid")
//like this:
//var entityRefs = result.Entities.Select(e=> e.GetAttributeValue<EntityReference>("new_alterunitorderid"));
var batchSize = 1000;
var batchNum = 0;
var numDeleted = 0;
while (numDeleted < entityRefs.Count())
{
var multiReq = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = false
},
Requests = new OrganizationRequestCollection()
};
var currentList = entityRefs.Skip(batchSize * batchNum).Take(batchSize).ToList();
currentList.ForEach(r => multiReq.Requests.Add(new DeleteRequest { Target = r }));
svc.Execute(multiReq);
numDeleted += currentList.Count;
batchNum++;
}