我正在尝试根据Silverlight控件中的Dynamics CRM中的Id检索一组实体。
我不知道将从查询中返回多少实体,但CRMs Rest服务每页只返回50条记录。因此,您必须继续构建集合,直到没有剩余页面可以从中检索。
我一直试图弄清楚如何让MainPage知道检索已经完成,并且没有剩余的记录要检索。我理想的是希望能够做到:
var opps = _crmManager.RetrieveOpportunities(accountId)
foreach (var opp in opps)
{
//do stuff here
}
我甚至不确定在这种情况下是否可行。 如果这是不可能的,我猜我将不得不做类似的事情:
_crmManager.OpportunitiesLoaded += OpportunitiesLoaded
private void OpportunitiesLoaded(sender s, EventArgs e)
{
foreach (var opp in _crmManager.Opportunities)
{
//Do work here
}
}
如果是这种情况,如何判断我的实体何时被完全检索并触发事件?
到目前为止我有这个设置:
//CrmManager.cs
private DataServiceCollection<Opportunity> _opportunity;
public DataServiceCollection<Opportunity> Opportunities
{
get { return _opportunity; }
set { _opportunity= value; }
}
public void RetrieveOpportunities(Guid accountId)
{
try
{
DataServiceQuery<Opportunity> query = (DataServiceQuery<Opportunity>)_context.OpportunitySet
.AddQueryOption("$filter", "AccountId/Id eq guid'" + accountId + "'");
query.BeginExecute(ProcessPages<Opportunity>, new PagingContext<Opportunity>()
{
ServiceContext = _context,
Query = query,
PageProcessor = delegate(DataServiceCollection<Opportunity> results)
{
try
{
if (null == Opportunities)
{
Opportunities= new DataServiceCollection<Opportunity>(_context);
Opportunities.Load(results);
}
else
{
for (int i = 0; i < results.Count; i++)
{
Opportunities.Add(results[i]);
}
}
}
catch (Exception ex)
{
//TODO catch
}
return true;
}
});
}
catch (SystemException ex)
{
//TODO Catch
}
}
//
private static void ProcessPages<T>(IAsyncResult result)
{
try
{
PagingContext<T> context = (PagingContext<T>)result.AsyncState;
QueryOperationResponse<T> response;
if (null == context.Query)
{
response = (QueryOperationResponse<T>)context.ServiceContext.EndExecute<T>(result);
}
else
{
response = (QueryOperationResponse<T>)context.Query.EndExecute(result);
context.Query = null;
}
DataServiceCollection<T> results = new DataServiceCollection<T>(response);
if (null != context.PageProcessor && !context.PageProcessor(results))
{
//Stop processing
return;
}
DataServiceQueryContinuation<T> token = results.Continuation;
if (null == token)
{
return;
}
context.ServiceContext.BeginExecute(token, ProcessPages<T>, context);
}
catch (Exception ex)
{
throw ex;
}
}
它正在使用的小型PagingContext类
sealed class PagingContext<T>
{
public DataServiceContext ServiceContext { get; set; }
public DataServiceQuery<T> Query { get; set; }
public Func<DataServiceCollection<T>, bool> PageProcessor { get; set; }
}
在MainPage上,我目前使用以下方法调用这些方法:
//MainPage.xaml.cs
_crmManager.RetrieveOpportunities(accountId)
foreach( var opportunity in _crmManager.Opportunities)
{
//Do work here
}
问题是这在某些时候有效。有时,Opportunities集合中有一些(并非所有)项目,它们将对这些项目起作用。其他时候,当我尝试访问它时,它仍然是空的。
非常感谢任何正确方向的帮助或推动。
答案 0 :(得分:0)
我找不到按照我的意愿去做的方法: 所以我最终在填充集合时触发了一个事件。 我将它添加到CrmManager类:
public delegate void CrmManagerEventHandler(object sender, EventArgs e);
public event CrmManagerEventHandler OpportunitiesPopulated;
然后在同一类的RetrieveOpportunities方法中:
if ((results.Continuation == null) && (OpportunitiesPopulated!= null))
{
OpportunitiesPopulated(this, e);
}
然后在MainWindow.xaml.cs中,我订阅了这个事件来做我想做的工作。在MainWindow.xaml.cs的设置中:
_manager.OpportunitiesPopulated += OpportunitiesPopulated;
实际方法:
private void OpportunitiesPopulated(object sender, EventArgs e)
{
//Do all the work here
}
只有在机会完成填充时才会解雇,这是我需要发生的事情。