1

フォームに統合することを目的とした Silverlight Web リソースを作成していますが、次のすべての情報を知る必要があります。

  • 現在のユーザーのID
  • 現在のユーザーが所属するチームの ID
  • 現在のユーザーのセキュリティ ロールの ID

私は事前にバインドされた方法で作業しており、サービス参照を OData エンドポイント ( ) に追加しました。これにより、コンテキストが提供されます (コードでの実際の名前であるhttp://server/org/XRMservices/2011/OrganizationData.svcという名前にしましょう)。cmtestcontext

私はこのクラスを介してデータにアクセスします (作成したわけではありません。少し前にネットでググっただけです。これは簡略化された簡潔なバージョンです)。

public class QueryInterface
{    
    //NOTE: ServiceReference1 is the name of the OData service reference
    //Add Service Reference -> point to CRM OData url
    public ServiceReference1.cmtextcontext CrmContext;
    public QueryInterface()
    {
        var crmServerUrl = (string)GetContext().Invoke("getServerUrl");
        if (crmServerUrl.EndsWith("/")) crmServerUrl = crmServerUrl.Substring(0, crmServerUrl.Length - 1);
        Uri ODataUri = new Uri(crmServerUrl + "/xrmservices/2011/organizationdata.svc/", UriKind.Absolute);
        CrmContext = new cmtestContext(ODataUri) { IgnoreMissingProperties = true };
    }   
}

このクラスを使用すると、次のように 1 行でフェッチを行うことができます (実際のコード スニペットは、コピーして貼り付けることができるようにダミー メソッドに含まれています)。

void RetrieveAllInformationFromCRM()
{
    QueryInterface qi = new QueryInterface();
    List<Guid> allData = new List<Guid>();

    //NOTE: STEP 1 - USER ID
    //NOTE: Since this is a web resource, I can cheat and use Xrm.Page.context.getUserId()
    //NOTE: Remove the extra '{}' from the result for it to be parsed!
    allData.Add(new Guid(qi.GetContext().Invoke("getUserId").ToString().Substring(1,36)));

    //NOTE: STEP 2a - TEAM MEMBERSHIP FOR USER
    //NOTE: TeamMembership entity links users to teams in a N:N relationship
    qi.crmContext.TeamMembershipSet.BeginExecute(new AsyncCallback((result) =>
    {
        var teamMemberships = qi.crmContext.TeamMembershipSet.EndExecute(result)
                              .Where(tm => tm.TeamId.HasValue && (tm.SystemUserId ?? Guid.Empty) == userId)
                              .Select(tm => tm.TeamId.Value);

        //NOTE: STEP 2b - TEAMS RELATED TO TEAMMEMBERSHIPS
        qi.crmContext.TeamSet.BeginExecute(new AsyncCallback((result2) =>
        {
            var teamDetails = qi.crmContext.TeamSet.EndExecute(result2)
                              .Where(t => teamMemberships.Contains(t.TeamId));

            foreach (var team in teamDetails) 
                allData.Add(team.TeamId);

            //NOTE: FINAL STEP - allData is filled and ready to be used.

        }), null);
    }), null);
}

上記のコードでは、 myFINAL STEPがそれを取得しallDataて処理し、フローが続きます。私の懸念は、この「リーダー」メソッドを変更する必要がある場合は、「最終」コードをカットアンドペーストして、すべての読み取り後に配置されるようにする必要があることです。読み取りが互いに続くようにすることができれば、もっと良い方法が欲しいので、これを行うことができます:

void MyReaderMethod()
{
     ReadEverything();
     ProcessData();
}

基本的には依頼が終わるのを待っていただけますか?ぶら下がっている UI は問題ではありBackgroundWorkerません。「お待ちください」というスプラッシュとともにコードをラップするだけです。

4

1 に答える 1

0

最も優れた (IMO) 方法は、非同期メソッド呼び出し (Silverlight の要件) をタスク ベースの呼び出しに変換することです。タスクを使用すると、結果アクションからクエリを簡単に分離できます。

次に、( nuget を介して) Async BCL を使用して、async/await を使用できます (VS2012 を使用していない場合でも、Tasks を使用する方が適切であり、継続を使用する必要があります)。

この例は遅延バインド用ですが、必要に応じて変更できます

 public Task<OrganizationResponse> ExecuteAsync(OrganizationRequest request)
        {
            return Task.Factory.FromAsync<OrganizationResponse>(
                (callback, state) => Begin(() => service.BeginExecute(request, callback, state)),
                   service.EndExecute,
                    null);
        }

次に、次のように使用できます

 async void MyReaderMethod()
    {
         //TODO:wrap in try/catch
         var result = await ExecuteAsync( ... );
         ProcessData(result);
    }

またはVS 2010の場合

 void MyReaderMethod()
        {
            ExecuteAsync( ... ).ContinueWith(task =>{

               //TODO: Error handling
               ProcessData(task.Result);

               });

        }
于 2013-08-28T15:47:26.723 に答える