2016-10-06 2 views
1

다음 코드 단편에서 주문 관련 메모를 검색하고 있습니다. notetext에 데이터가있는 경우에만 제대로 작동합니다. 자, 디버깅하는 동안 나는 그것을 발견했다. 다른 경우에는 Object reference not set to an instance of an object이라는 예외를 throw한다.Entity.Contains (AttributeName)는 모든 주석 필드에서 작동하지만 notetext에서는 작동하지 않습니다.

다음 스 니펫이 좋아 보이지만 문제가 무엇인지 놓치지 않았는지 생각해보십시오.

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"); 
    }  
} 
+0

하여 Null 참조 오류, 또는 :

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

Decomplied SDK 캐시기구 Serivce 상황에 맞는 여러 검색 :

Decomplied SDK는 여러 개의 코어를 검색 null입니까? – Daryl

+0

여기에 excpetion이 throw됩니다. if (defaultRecord.Contains ("notetext")) " –

답변

1

문제는이 라인에서 실제로 :

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

의미를 발견 결과가, 없다가 "vOrderId"의 OBJECTID에 존재하는 어떤 주석도 없다, 또는 쿼리를 수행하는 사용자는 해당 레코드를 읽을 수있는 권한이 없습니다.

defaultRecord이 null인지 아닌지 확인하고 존재하는 경우 종료해야합니다. 이것은이 당신의 코드를 단순화 할

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

을 당신은 보호하지 않은

널 (null)이 체크 내가이 ExtensionMethod를 작성한 이유는 일반적인 현상이며, 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 특성 : 어떤 객체

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; 
    } 
} 
은 무엇 라인
+0

'Results.Entities'는 결코 null이 아닙니다. 그것을 확인할 이유가 없습니다. 또한'Any' 체크를 추가하는 것은'defaultRecord'가 null이 아닌 경우에 추가 단계입니다. 'ElementAtOrDefault'를 사용하여'defaultRecord'를 검색하고'defaultRecord'가 null인지 확인하는 것이 좋습니다. 마침내 IMHO는 "if"문과 함께 "!" 그 전체 문장은 "! =" – Daryl

+0

@Daryl보다 읽기 쉽지 않습니다. 당신의 문장'Result.Entities는 결코 null이 될 수 없습니다. 여기에 언급 된 내용이 없습니다. https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.messages.retrievemultipleresponse.aspx. 차라리 SDK/API를 사용하여 안전하다고 생각하고 추가 체크를 수행합니다. '.Any()'는 데이터를 가져오고 요소를 반복하고, 요소가 발견되면 bool을 리턴 할 때만 데이터를로드하는 것이 중요합니다. elementordefault가 null인지 확인하는 것과 같습니다. '! Any()'는'All()'보다 읽기 쉽습니다. – dynamicallyCRM

+0

SDK에 대한 분해 된 소스 코드를 살펴보면 설정 한 소스 코드를 볼 수 있습니다. 또한'Entities' 속성은 읽기 전용입니다. 즉, 'Add' 메서드가 노출되지 않았거나 그렇지 않으면 인스턴스화하는 메서드를 제공하지 않으므로 생성자에서 속성을 인스턴스화해야합니다. – Daryl