Entity.Contains(AttributeName)适用于所有注释字段,但不适用于notetext

本文关键字:适用于 字段 notetext 不适用 注释 Contains AttributeName Entity | 更新日期: 2023-09-27 18:11:41

在下面的代码片段中,我正在检索与订单相关的注释。只有当notetext包含数据时,它才能正常工作。现在,在调试时我发现,在其他情况下,它会抛出异常,Object reference not set to an instance of an object .

我认为下面的片段看起来不错,但不确定缺少什么,有什么想法来解决问题吗?

private void fetchDocument(IOrganizationService service, Guid vOrderId) 
{
    EntityCollection results = null;
    string tempNote = string.Empty;
    string tempFileName = string.Empty;
    ColumnSet cols = new ColumnSet("subject", "filename", "documentbody", "mimetype","notetext");
    QueryExpression query = new QueryExpression {
            EntityName = "annotation" ,
            ColumnSet = cols,
            Criteria = new FilterExpression
            {
                Conditions = {
                new ConditionExpression("objectid",ConditionOperator.Equal,vOrderId)
            }
            }
            };
    results = service.RetrieveMultiple(query);
    Entity defaultRecord = results.Entities.ElementAtOrDefault(0);
    if(defaultRecord.Contains("notetext"))
    {
        tempNote = defaultRecord.GetAttributeValue<string>("notetext");
    }
    if (defaultRecord.Contains("filename"))
    {
        tempFileName = defaultRecord.GetAttributeValue<string>("filename");
    }       
}

Entity.Contains(AttributeName)适用于所有注释字段,但不适用于notetext

您没有保护defaultrecord免受null。

results = service.RetrieveMultiple(query);
if (results.Entities == null || !results.Entities.Any()) return;
Entity defaultRecord = results.Entities.ElementAt(0);

将答案扩展到备份result.Entities == null检查。

检索多个EntityCollection不是万无一失的。

EntityCollection property:

解压SDK检索多核:

  protected internal virtual EntityCollection RetrieveMultipleCore(QueryBase query)
    {
      bool? retry = new bool?();
      do
      {
        bool forceClose = false;
        try
        {
          using (new OrganizationServiceContextInitializer(this))
            return this.ServiceChannel.Channel.RetrieveMultiple(query);
        }
        catch (MessageSecurityException ex)
        {
          ..
        }
        finally
        {
          this.CloseChannel(forceClose);
        }
      }
      while (retry.HasValue && retry.Value);
      return (EntityCollection) null;
    }

反编译SDK缓存组织服务上下文检索多个:

public override EntityCollection RetrieveMultiple(QueryBase query)
{
   RetrieveMultipleRequest retrieveMultipleRequest = new      RetrieveMultipleRequest();
   retrieveMultipleRequest.Query = query;
   RetrieveMultipleResponse multipleResponse = this.Execute<RetrieveMultipleResponse>((OrganizationRequest) retrieveMultipleRequest);
   if (multipleResponse == null)
     return (EntityCollection) null;
   else
     return multipleResponse.EntityCollection;
}

public EntityCollection EntityCollection
{
   get
   {
     if (this.Results.Contains("EntityCollection"))
        return (EntityCollection) this.Results["EntityCollection"];
     else
        return (EntityCollection) null;
   }
}

您的问题实际上在这一行:

Entity defaultRecord = results.Entities.ElementAtOrDefault(0);

There is no results found,意思是

不存在目标为"vOrderId"的Annotation,或者执行查询的用户没有权限读取该记录。

无论如何,您应该检查defaultRecord是否为空,如果是,则退出。

null检查是一个常见的现象,这就是为什么我写了这个ExtensionMethod:

public Entity GetFirstOrDefault(this IOrganizationService service, QueryBase qb) {
    return service.RetrieveMultiple(qb)?.Entities.FirstOrDefault();
}

这样可以简化代码:

private void fetchDocument(IOrganizationService service, Guid vOrderId) 
{
    EntityCollection results = null;
    string tempNote = string.Empty;
    string tempFileName = string.Empty;
    ColumnSet cols = new ColumnSet("subject", "filename", "documentbody", "mimetype","notetext");
    QueryExpression query = new QueryExpression {
            EntityName = "annotation" ,
            ColumnSet = cols,
            Criteria = new FilterExpression
            {
                Conditions = {
                new ConditionExpression("objectid",ConditionOperator.Equal,vOrderId)
            }
            }
            };
    var defaultRecord = service.GetFirstOrDefault(query);
    if(defaultRecord != null)
    {
        if(defaultRecord.Contains("notetext"))
        {
             tempNote = defaultRecord.GetAttributeValue<string>("notetext");
        }
        if (defaultRecord.Contains("filename"))
        {
            tempFileName = defaultRecord.GetAttributeValue<string>("filename");
        } 
    }
}