我正在构建一个旨在集成到表单中的 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 };
}
}
该类允许我在一行中进行排序,如下所示(实际代码片段包含在一个虚拟方法中以使其可复制粘贴):
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
与“请稍候”飞溅一起包装。