2013-01-15 5 views
3

this blog에는 필드의 메타 데이터를 검색하는 방법이 나와 있습니다.필드가 정의되어 있는지 확인하는 방법은 무엇입니까?

위의 내용 이외에 try-catch-statement와 결합하여 확인하는 방법을 알고 싶습니다. 필드의 존재 여부.

그 이유는 내가 내 QueryExpression을 실행할 때, 나는 ColumnSet에 포함 할 열을 알 필요가 있다는 것입니다.

Q & D 코드는 지금입니다.

private bool DoesFieldExist(String entityName, String fieldName) 
{ 
    try 
    { 
    RetrieveAttributeRequest req = new RetrieveAttributeRequest(); 
    req.EntityLogicalName = entityName; 
    req.LogicalName = fieldName; 
    RetrieveAttributeResponse resp = (RetrieveAttributeResponse)service.Execute(req); 
    } 
    catch (Exception) { return false; } 
    return true; 
} 
+0

사용중인 코드를 게시하면 안드레아스가 좋을 것입니다 .. – MethodMan

+0

모든 열을 검색 하시겠습니까, 아니면 문자열 목록을 갖고 싶고 기존 목록 만 선택 하시겠습니까? – ccellar

+0

@DJKRAZE 아주 좋은지 확실하지 않습니다. 오히려 못생긴 해결책입니다. 그것은 작동하지만 그것은지도가 정확한지 확인하기 위해 벽에 차를 부딪 치는 것과 같습니다. : D –

답변

5
private bool DoesFieldExist(String entityName, String fieldName) 
{ 
    RetrieveEntityRequest request = new RetrieveEntityRequest 
    { 
    EntityFilters = Microsoft.Xrm.Sdk.Metadata.EntityFilters.Attributes, 
    LogicalName = entityName 
    }; 
    RetrieveEntityResponse response 
    = (RetrieveEntityResponse)service.Execute(request); 
    return response.EntityMetadata.Attributes.FirstOrDefault(element 
    => element.LogicalName == fieldName) != null; 
} 
  1. EntityFilters이 요구하는 접근은 당신이 제대로 작동하기 위해 using Microsoft.Xrm.Sdk.Metadata;를 추가 할 수 없다고 정의되어 있는지 여부를 확인 (그리고 추악하기 때문에 그것을 싫어하는 것이 좋습니다).

  2. SingleOrDefault 대신 FirstOrDefault을 사용하고 싶습니다. 이 경우에는 문제가 발생하지 않지만 (입니다), 조건을 만족하는 요소가 여러 개있는 경우 예외가 발생할 수 있습니다 (여러 속성에 일치하는 항목을 찾아야하는 경우) 또는 그 원인이 될 수있는 다른 일을하십시오).

3

또 다른 가능성은 엔터티에 대한 EntityMetadata를로드하는 것입니다.

var request = new RetrieveEntityRequest 
{ 
    EntityFilters = EntityFilters.Attributes, 
    LogicalName = entityName 
}; 

var response = (RetrieveEntityResponse)_serviceProxy.Execute(request); 

성능상의 이유로 메모리 나 디스크에 캐시 할 수 있습니다. 위해서는 속성이 내 예제에서 명시 적 참조를 싫어하는 경우 속성 속성

var defined = response.EntityMetadata 
         .Attributes 
         .SingleOrDefault(a => a.LogicalName == fieldName) != null; 
+0

이상합니다. 'EntityFilters'에 오류가 있습니다 ... 저는 지금 약간의 스트레스를 받았다고 생각합니다. 꽤 쉽지만, 모든 것이 잘못되어가는 것처럼 느껴집니다 ... 무엇을 놓치겠습니까? –

+0

@AndreasJohansson 어떤 오류가 있습니까? SDK 어셈블리 – ccellar

+0

에 대한 참조를 설정 했습니까? 나는 다른 답장에서 그것을 보았다. 내 나쁜 ... –

2

나는 게임에 약간 늦다는 것을 알고 있지만, 이것을하기를 원하는 사람들에게 더 좋은 대안을 추가하고 싶습니다.

일종의 캐싱을 도입하지 않으면 메타 데이터 호출 속도가 매우 느립니다. 메타 데이터 호출을 정기적으로 실행되는 플러그인에 넣으면 문제가 생길 수 있습니다. (MS는 메타 데이터 호출이 왜 느리며 고쳐야 하는지를 정말로 봐야합니다!).

단순히 필드의 존재를 확인하면 예외가 발생하는 것입니다. 허락하지 않았고, 일부 전도자는 싫어했지만 메타 데이터 호출보다 최대 3 배 빠른 실행을 발견했습니다. 최소한 정기적으로 플러그인을 실행하려면 수용 할 수있는 괄호 안에 넣어야합니다.

try 
{ 
    var query = new QueryExpression("account"); 
    query.Criteria.AddCondition("accountid", ConditionOperator.Equal, "294450db-46c9-447e-a642-3babf913d800"); 
    query.NoLock = true; 
    query.ColumnSet = new ColumnSet("xyz_fieldname"); 
    service.RetrieveMultiple(query); 
} 
catch 
{ 
    // ignored 
} 

이 장점을 가지고, 당신은 기본 키 ID 인을 실행하고는 (당신이 ID를 걱정하지 않는다 쿼리 식을 사용하여 :

내가 대신 할 것입니다 필드가 없으면 코드에서 예외를 throw하거나 성공하면 1을 반환하거나 레코드를 반환하지 않습니다. 간단히 말해서, 목적은 레코드를 찾는 것이 아니라, 컬럼을 포함시키는 것이 예외인지 확인하는 것입니다.

쿼리 식의 두 번째 장점은 nolock을 사용하여 실행할 수 있다는 것입니다.당신은 결과 세트에 대해별로 신경 쓰지 않는다. 요점은 예외를 강요한다.

여러 가지/단일 호출을 메타 데이터에 대한 여러/단일 호출 (C# stopwatch 및 코드 순서를 사용하여 등) 예외를 throw하는 여러 호출을 검색하는 여러 온라인 테스트를 실행했습니다. 예외는 항상 메타 데이터를 능가했습니다. 동일한 코드 내에서 여러 번 호출을 수행하는 경우 약 3 배 빠른 속도로 이동합니다 (최적화가 작동한다고 생각합니다). 어느 쪽이든 병 목은 메타 데이터 서비스에 대한 호출이며, 캐싱과 더 많은 코드 복잡성을 도입 할 때까지는 최적화 할 수 없습니다. 또한 필드가 존재하는 경우 예외를 얻지 못해 또 다른 성능 보너스를 의미합니다.

내가 테스트하지 않은 유일한 시나리오는 엄청나게 많이 사용되는 엔티티에 대해 실행하는 것입니다.하지만 데이터베이스를 너무 세게 치고 있으면 nolock 검색이 허용되는 시간대에 반환되지 않을 수 있습니다. 걱정해라!

+1

+1이 솔루션은 더 많은 관심을 가져야한다. 예외를 강제하는 것은 내가 일반적으로 좋아하는 것이 아니라는 것이 사실이지만,이 특별한 경우에는 속도 향상이 그만한 가치가 있습니다. – tsukumogami

관련 문제