为什么记录不删除?

时间:2018-08-06 05:53:54

标签: dynamics-crm microsoft-dynamics dynamics-365

我编写了一个插件,该插件通过fetchXML获取GUID ID,并使用Batch Delete批量删除1000条记录。

我调试了插件,它显示插件一直执行到service.RetrieveMultiple(new FetchExpression(fetchxml)),但是,获取的记录没有被删除。有人可以解释为什么吗?这是插件代码:

using System;
using System.Linq;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;


/// <summary>
/// This plugin will trimm off unit orders after a contract is cancelled before the end of the contract duration
/// </summary>

namespace DCWIMS.Plugins
{

    [CrmPluginRegistration(MessageNameEnum.Update,
    "contract",
    StageEnum.PostOperation,
    ExecutionModeEnum.Asynchronous,
    "statecode",
    "Post-Update On Cancel Contract",
    1000,
    IsolationModeEnum.Sandbox,
    Image1Name = "PreImage",
    Image1Type = ImageTypeEnum.PreImage,
    Image1Attributes = "")]

    public class UnitPluginOnCancel : IPlugin
    {

        public void Execute(IServiceProvider serviceProvider)
        {
            // Extract the tracing service for use in debugging sandboxed plug-ins.
            // Will be registering this plugin, thus will need to add tracing service related code.

            ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            //obtain execution context from service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Output Parameters collection contains all the data passed in the message request. 

            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is Entity)
            {

                Entity entity = (Entity)context.InputParameters["Target"];

                //Get the before image of the updated contract
                Entity PreImage = context.PreEntityImages["PreImage"];


                //verify that target entity is contract and contains a cancellation date
                if (entity.LogicalName != "contract" || entity.GetAttributeValue<OptionSetValue>("statecode").Value != 4)
                    return;

                if (PreImage.GetAttributeValue<OptionSetValue>("statecode").Value == 0 || entity.Contains("cancelon"))
                    return;

                if (PreImage.GetAttributeValue<OptionSetValue>("statecode").Value == 3 || PreImage.GetAttributeValue<OptionSetValue>("statecode").Value == 1)
                    return;

                //obtain the organization service for web service calls.
                IOrganizationServiceFactory serviceFactory =
                    (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);


                //Core Plugin code in Try Block
                try
                {

                    //Get Contract line start date
                    var startDate = PreImage.GetAttributeValue<DateTime>("cancelon");

                    //Get Contract Line End Date
                    DateTime endDate = (DateTime)PreImage["expireson"];

                    //Get Contract range into weekdays list
                    Eachday range = new Eachday();
                    var weekdays = range.WeekDay(startDate, endDate);

                    //Get Unit Order Lookup Id
                    EntityReference unitOrder = (EntityReference)PreImage.Attributes["new_unitorderid"];

                    var unitOrders = service.Retrieve(unitOrder.LogicalName, unitOrder.Id, new ColumnSet("new_name"));
                    var unitOrdersId = unitOrders.Id;

                    var uiName = unitOrders.GetAttributeValue<string>("new_name");

                    //Get Entity Collection to delete 

                    string fetchXml = @" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false' top='2000'>
                        <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.ToString("yyyy-MM-dd") + @"' />
                                    <condition attribute='new_orderdate' operator='on-or-before' value='" + endDate.ToString("yyyy-MM-dd") + @"' />
                                    <condition attribute='new_orderlineid' operator='eq' uiname='" + uiName + @"' uitype='new_units' value='" + unitOrdersId + @"' />
                                </filter>
                            </link-entity>
                        </entity>
                    </fetch>";


                    var result = service.RetrieveMultiple(new FetchExpression(fetchXml));

                    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 }));

                        service.Execute(multiReq);

                        numDeleted += currentList.Count;
                        batchNum++;
                    }


                }
                catch (FaultException<OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("An error occured.. Phil is responsible. ", ex);
                }
                catch (Exception ex)
                {
                    tracing.Trace("An error occured: {0}", ex.ToString());
                    throw;
                }
            }


        }

    }

}

我尝试过:

var entityGuids = result.Entities.Select(ent => ent.GetAttributeValue<Guid>("new_alterunitorderid"));
var entityRefs = entityGuids.Select(guid => new EntityReference("new_alterunitorder", guid));

知道了:

guids are not being retrieved

2 个答案:

答案 0 :(得分:2)

我认为错误是在您执行RetrieveMultiple请求之后立即出现的

var entityRefs = result.Entities.Select(e => e.GetAttributeValue<EntityReference>("new_alterunitorderid"));

new_alterunitorderid不是EntityReference。这是主键。

代替尝试:

var entityRefs = result.Entities.Select(e => e.ToEntityReference());

您还应该利用tracing对象在跟踪日志中包含更多输出:

 tracing.Trace("Executing query");
 var result = service.RetrieveMultiple(new FetchExpression(fetchXml));
 tracing.Trace("{0} results found. Converting to EntityReferences", result.Entities.Count);
 var entityRefs = result.Entities.Select(e => e.ToEntityReference());

答案 1 :(得分:1)

通常,批处理作业是异步的。进入设置>系统作业。搜索您的删除作业。我从未使用过这种特定的语法,但是逻辑似乎还可以。