2017-10-09 15 views
0

다른 엔티티를 유사하게 표시 할 수 있도록 인터페이스를 일반화 된 상태로 유지하면서 견적서의 견적 라인을 나열하고 싶습니다.Dynamics CRM C# SDK - 견적 라인의 이름을 가져 오려고했지만 필드가 존재하지 않습니까?

이렇게하려면 EntityMetadata에있는 PrimaryNameAttribute를 사용하려고합니다. 대부분의 엔티티에서 훌륭하게 작동하지만 QuoteDetail의 경우 PrimaryNameAttribute는 "productidname"입니다. 실제로는 QuoteDetail 엔티티의 일부로 존재하지 않는 속성입니다.

이 필드 "productidname"은 다른 엔터티 (OpportunityProduct, SalesOrderDetail)의 PrimaryNameAttribute이기도하며이 경우 필드도 누락됩니다.

무엇을 제공합니까? 나는 Google을 모두 검색 한 것처럼 느껴지고 이전에이 문제가 발생하지 않은 것처럼 보였으므로 무언가 간단한 것을 누락시킨 것일 수 있습니다.

여기 제가 말하고자하는 것을 보여주는 MSDN의 QuoteDetail 엔티티 페이지가 있습니다 : https://msdn.microsoft.com/en-us/library/mt607959.aspx PrimaryNameAttribute가 페이지의 다른 곳에 나열되지 않습니다.

답변

1

QuoteDetail (SalesOrderDetail 및 OpportunityProduct와 같은)은 Catalog Product 항목 또는 Write-In 항목에 대한 관계 엔터티 일 수 있고 productidname (카탈로그 제품) 또는 productdescription (write- 제품). 이름을 얻으려면 관련 제품에 가입해야합니다.

일반적인 솔루션/인터페이스를 개발하려는 경우 모든 Lookup 특성을 해결하는 데 필요한 문제입니다.

string productname; 
quotedetail.FormattedValues.TryGetValue("productid", out productname); 
:/안전하면서도 더 나은

string productname = quotedetail.FormattedValues["productid"]; 

: 당신이 오직 조회로 연결 기록에서 PrimaryNameAttribute 필요한 경우

, 당신은 당신의 "주"기업의 FormattedValues 모음에서 이름을 검색 할 수 있습니다 다음과 같이 할 수있는 임의의 개체의

취급 속성 :

foreach (var key in record.Attributes.Keys) 
{ 
    if (record.FormattedValues.ContainsKey(key)) 
    { 
     string formattedvalue; 

     if (record.FormattedValues.TryGetValue(key, out formattedvalue)) 
     { 
      Console.WriteLine(formattedvalue); // use formattedvalue string 
     } 

     continue; // skip to next field when found in formatted values 
    } 

    object attributevalue; 

    record.Attributes.TryGetValue(key, out attributevalue); 

    object actualvalue; 
    string actualtext = string.Empty; 

    // handle AliasedValue fields from JOINed/LinkEntities 
    if (attributevalue.GetType().Name == "AliasedValue") 
    { 
     actualvalue = ((AliasedValue)attributevalue).Value; 
    } 
    else 
    { 
     actualvalue = attributevalue; 
    } 

    switch (actualvalue.GetType().Name) 
    { 
     case "EntityReference": 
      actualtext = ((EntityReference)actualvalue).Name; // this will catch Lookup values not contained in FormattedValues when you just created them 
      break; 

     case "DateTime": 
      actualtext = string.Format("{0:dd.MM.yyyy}", ((DateTime)actualvalue).ToLocalTime()); // ... any other dateTime format you'd like 
      break; 

     case "Guid": 
      actualtext = string.Format("{0:D}", actualvalue); // Entity Primary key 
      break; 

     default: 
      actualtext = (string)actualvalue; // anything else 
      break; 
    } 

    Console.WriteLine(actualtext); 
} 

새로 할당 된 OptionSetValueMoney 속성 (EntityReference 것과 비슷 함)은 보통 FormattedValues에서 가져온 것이므로 처리해야합니다.

이 예제는 기존 crm 데이터를 처리하기 때문에 엔티티에 모든 특성이 포함되지 않을 것이라는 함정을 인식해야하므로 .Attributes.Keys을 반복하는 대신 사전 정의 된 특성 이름 집합을 검토 할 수 있습니다.

내 개인적인 전략은 일반적으로 입력 된 개체와 CRM 엔티티간에 매핑 할 수있는 간단한 ORM을 만드는 것이지만 이는 일반 인터페이스 요구 사항에 맞지 않습니다. 이 중 이런 저런 속성이 내가 일을 구문 설탕을 넣고있어 귀사와 같은 경우에


:

string pn = qd.GetAttributeValue<string>("productdesription") ?? (qd.GetAttributeValue<EntityReference>("productid") ?? new EntityReference { Name = string.Empty }).Name; 

시도를 쓰기에서 제품 이름을 가져; 그것이 null의 경우, Lookup의 이름을 취득 해, null의 경우, 위조 된 EntityReference로부터 빈 상태 (empty)의 캐릭터 라인을 취득합니다.

이것은 마찰이 적은 코딩을 허용하고 "이 속성 또는 그 속성"을 멋지게 해결합니다.

+0

감사합니다. 관련 엔티티/필드를 필요에 따라 가져 오기 위해 코드를 지시 할 수있는 메타 데이터에 뭔가가 있습니까? 아니면 문제를 해결하기 위해 내 솔루션에 하드 코딩해야 할 것입니까? – Yoni

+0

업데이트를 보았습니다. 곧 그걸 시도 할 것이다. 다시 한번 감사드립니다. – Yoni

+0

업데이트 예를 통해 일반적인 아이디어를 얻을 수 있습니다. 나중에 임의의 속성을 추출하는 방법에 대한 전체 코드 예제를 추가하겠습니다. – Filburt