2011-09-15 3 views
2

동적 엔터티 (Microsoft.Xrm.Sdk.Entity, 후기 바인딩 메서드)를 통해 CRM 2011 데이터를 사용하는 서비스를 개발 중입니다. 나는 고의적으로 Xrm.cs 메서드 (초기 바인딩)를 사용하여 내 솔루션을 일반화하지 않았습니다.CRM 2011 Dynamic Entity를 사용하여 레코드 비율 지정

CRM 데이터베이스 (예 : EDMX)에 직접 연결하는 것을 피면 내 솔루션이 호스팅 된 CRM에 사용할 수 없게됩니다 (예 : 직접 DB 액세스가없는 경우).

나는 정말 선택 기준과 사투를 벌인거야, 다음 (간체) 요구 사항이 :

임의 7 % 필요 기록이 선택 될 (업데이트).

SQL에서는 선택 기준이 상대적으로 쉽습니다. 레코드의 임의 비율을 선택하는 방법을 알고 있습니다. 예 :

SELECT TOP 7 PERCENT * FROM 
(
    SELECT TOP 1000 NEWID() AS Foo, [someColumns] 
    FROM [someTable] 
) 
AS Bar ORDER BY Bar.Foo ASC 

이것은 완벽하게 작동합니다. 내가 CRM 2011 동적 엔티티 LINQ를 사용하는 방법을 알고하지 않는 문제가 있지만있다

from e in someEntities 
orderby Guid.NewGuid() 
select e; 

- 대신 그들은 몇 가지 제한 QueryExpression 클래스/구문을 사용하여 주장 : 뭔가처럼 LINQ에 해당이 수집 , 또는 fetchXML을 사용합니다 (this page (MSDN) 참조).

나는이 요구 사항을 충족하기위한 다음과 같은 옵션을 확인했습니다

  1. 은 단순히 인덱스에 의해 임의 선택을 선택 목록으로 설정 전체 기록을 반환, 동적 엔티티를 사용. 그러나 이것은 인터넷 데이터 서비스를 통해 최대 10,000 개의 레코드를 반환하는 것을 포함하는데 이는 느리거나 불안정 할 수 있습니다.

  2. fetchXML 문을 사용하십시오. 불행히도 나는 fetchXML을 모른다. 따라서 COUNT, TOP, PERCENT 또는 NEWID()와 같은 일을 할 수 있는지는 알 수 없다.

  3. Xrm.cs 및 LINQ를 사용하거나 저장 프로 시저 또는 SQL보기를 사용하십시오. 이러한 모든 옵션은 솔루션을 직접적인 데이터베이스 연결 및/또는 초기 바인딩으로 묶는 것을 의미합니다. 이는 바람직하지 않습니다.

  4. 고객에게 말하십시오.

모든 조언을 주시면 감사하겠습니다. fetchXML이이 쿼리를 수행 할 수 있습니까? 이 작업을 수행하는 더 좋은 방법이 있습니까?

답변

2

FetchXML은이 기능을 지원하지 않으므로 1 또는 3으로 내려갑니다. CRM 온라인 제품을 사용하여 SQL에 직접 연결할 수 없기 때문에 3은 온 프레미스 버전에서만 작동합니다. 그러나 고객이 CRM Online으로 이동할 것이라는 것을 절대 확신하지 않는 한, 내가 간다고 할 수 있습니다. 1로 가야 할 경우 적어도 페이로드 크기를 줄이기 위해 반환 된 열을 레코드의 GUID로만 ​​제한 할 수 있습니다. 그런 다음 임의의 레코드를 선택하면 필요에 따라 추가 열을 가져옵니다 (물론 이것은 무작위 레코드 수에 따라 "chattiness"로 인해 느려질 수 있습니다).

+0

저는 요구 사항 작성자가 솔루션이 호스트 된 환경에 적용 가능해야한다는 점을 강조합니다. 따라서 ID 목록을 반환하고 해당 항목을 무작위로 추출해 보겠습니다. 나는이 방법이 성공적으로 입증되면 업적으로 표시하고 답변으로 표시합니다. 고마워 :) – Alec

+0

나는 위에서 설명한 방법을 사용하여이 작업을 할 수 있었다. 전체 집합을 ids의 목록으로 반환 한 다음 임의적 인 메모리 내 선택을 수행 한 후 전체 데이터를 선택합니다. 그래서 나는 이것을 답으로 쓰겠습니다. 그러나 비슷한 요구 사항을 가진 사람이라면 jamnap의 답을 읽어야합니다. 나는 어느 솔루션이 더 효율적인 지 아직 모른다. – Alec

2

Dynamics CRM 2011에서는 SQL 및 기타 LINQ 공급자가 제공 할 수있는 쿼리의 수준을 알 수 없으므로 고객에게 을 말하고으로 이동하려고합니다. 그/그녀가 그런 종류의 융통성을 원한다면 온 - 프레미스 버전.

이 말처럼, 방법 1의 변형은 한 번에 모든 행을 가져온 다음 임의의 집합을 선택하는 대신 행 수를 가질 때까지 한 번에 한 행씩 임의의 행을 가져옵니다. 네가 원해. 이 방법의 단점은 DB를 한 번 호출하는 대신에 전체를 검색하는 속도가 느려지는 많은 것이 있다는 것입니다. POC는 아래에 있습니다.

# 2의 경우 fetchXml을 사용하여 어느 정도의 성공과 함께 모든 요청을 처리 할 수 ​​있다고 생각합니다. 실제로 aggregated data을 얻는 유일한 방법은 fetchXml을 사용하는 것이며 paging도 지원합니다.

# 3의 경우, 네이티브 SQL은 현재 데이터에서 원하는 모든 것을 얻을 수있는 최선의 방법이지만 the LINQ provider is limited은 SQL 문을 fetchXML보다 LINQ로 전환하는 것이 훨씬 쉽습니다. it does support late-binding/dynamic entities.

//create a list of random numbers 
List<int> randomNumbers = new List<int>(); 

//declare a percentage of records you'd like to retrieve 
double pctg = 0.07; 

//use FetchXML to count the # of rows in the table 
string fetchXml = @"<fetch aggregate='true'> 
<entity name='salesorder'> 
<attribute name='salesorderid' aggregate='count' alias='countIds' distinct='false' /> 
</entity> 
</fetch>"; 
EntityCollection result = _service.RetrieveMultiple(new FetchExpression(fetchXml)); 
int rowCount = int.Parse(result.Entities[0].FormattedValues["countIds"].Replace(",", "")); 

//initalize the random number list for paging 
for (int i = 0; i < Math.Ceiling(pctg * rowCount); i++) 
{ 
    randomNumbers.Add((new Random(unchecked((int)(DateTime.Now.Ticks >> i)))).Next(rowCount - 1)); 
} 
randomNumbers.Sort(); 

//page through the rows one at a time until you have the number of rows you want 
using (OrganizationServiceContext osc = new OrganizationServiceContext(_service)) 
{ 
    foreach (int r in randomNumbers) 
    { 
     foreach (var er in (from c in osc.CreateQuery("salesorder") 
          //not especially useful to use the orderby option as you can only order by entity attributes 
          //orderby c.GetAttributeValue<string>("name") 
          select new 
          { 
           name = c.GetAttributeValue<string>("name") 
          }).Skip(r).Take(1)) 
     { 
      Console.WriteLine(er.name); 
     } 

    } 
} 
+0

저는 페이징 쿠키를 사용하지 않을 것입니다 - 좋은 생각입니다! –

+1

이 답변에서 매우 흥미로운 정보로, MSDN 링크에 표시된 방식으로 LINQ를 동적 엔터티와 함께 ​​사용할 수 있다는 것을 알지 못했습니다. FetchXML이이를 수행하는 더 좋은 방법 일 수 있습니다. 제안 된 다른 방법과 성능면에서 어떻게 비교되는지 실험 해 보겠습니다. 응답에 대한 많은 감사드립니다. – Alec

관련 문제