2011-09-15 7 views
2

ダイナミックエンティティ(Microsoft.Xrm.Sdk.Entity、レイトバインディングメソッドのように)を使用してCRM 2011データを使用するサービスを開発しています。私は故意にXrm.csメソッド(初期バインディング)を使用して、私のソリューションを一般的なものに保ちません。CRM 2011ダイナミックエンティティを使用してレコードの割合を選択

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のいずれかになります.3つは、CRM Online製品でSQLに直接接続できないため、On Premiseバージョンでのみ機能します。しかし、顧客がCRM Onlineに移行することを確実に確かめることができない限り、それは私が進めるものです。 1を指定する必要がある場合は、返される列を少なくともレコードのGUIDに制限して、ペイロードサイズを小さくすることができます。その後、ランダムなレコードを選択するときには、必要に応じて追加の列を取得してください(もちろん、ランダムなレコードの数に応じて、 "チャタニー"のために遅くなります)。

+0

要件作成者は、ソリューションがホストされた環境に適用可能であることを確信していると思いますので、idsのリストを返してそれらをランダム化することにします。私は投票しました。この方法が成功すれば、答えとしてマークします。ありがとう:) – Alec

+0

私は上記の方法を使用してこの作業を行うことができました。完全なセットをIDのリストとして返すだけで、メモリ内のランダムな選択を行った後で完全なデータを選択します。だから私はこれを答えとして置くでしょうが、同様の要件を持つ誰もがjamnapの答えの情報を読むべきであると推薦します。私はまだどのソリューションがより効率的であるかはわかりません。 – Alec

2

Dynamics CRM 2011では、SQLと他のLINQプロバイダが提供できる権限をクエリすることはできません。したがって、といいますとに移動したいと考えています。そのような柔軟性が必要な場合は、オンプレミス版を使用してください。

これは、一度にすべての行をフェッチしてランダムセットを選択するのではなく、行数を持つまで一度に1行ずつランダムセットをフェッチするのではなく、あなたは欲しい。このメソッドの欠点は、DBへの1回の呼び出しの代わりに、全体の検索速度を遅くするものが多数あることです。 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

関連する問題