公共视图的查询定义存储在savedquery实体中,可以使用常用技术进行查询。
开箱即用的视图使用固定 ID 存储,因此可以通过以下方式查询 OrganizationServiceContext 对象上的活动帐户:
private static IEnumerable<Entity> GetActiveAccounts(OrganizationServiceContext serviceContext)
{
string fetchXml = serviceContext
.CreateQuery("savedquery")
.Where(sq =>
sq.GetAttributeValue<Guid>("savedqueryid") == new Guid("00000000-0000-0000-00AA-000010001002"))
.Select(sq => sq.GetAttributeValue<string>("fetchxml"))
.First();
var request = new RetrieveMultipleRequest
{
Query = new FetchExpression(fetchXml)
};
var response = (RetrieveMultipleResponse) serviceContext.Execute(request);
return response.EntityCollection.Entities;
}
这里不能使用 LINQ。 LINQ 依赖于QueryExpression 类,但并未实现其所有功能(例如,OUTER JOIN 是一个痛苦的遗漏)。因此,虽然可以将 LINQ 查询转换为 QueryExpression,但反之则不行。
可以通过编辑 Fetch XML 字符串来应用分页,但如果这太麻烦,您还可以考虑将 Fetch XML 转换为 QueryExpression 并在该对象上应用分页:
private IEnumerable<Entity> GetActiveAccounts(int pageNumber)
{
string fetchXml = _serviceContext
.CreateQuery("savedquery")
.Where(sq =>
sq.GetAttributeValue<Guid>("savedqueryid") == new Guid("00000000-0000-0000-00AA-000010001002"))
.Select(sq => sq.GetAttributeValue<string>("fetchxml"))
.First();
var conversionRequest = new FetchXmlToQueryExpressionRequest
{
FetchXml = fetchXml
};
var response = (FetchXmlToQueryExpressionResponse)_serviceContext.Execute(conversionRequest);
response.Query.PageInfo = new PagingInfo { Count = 1, PageNumber = pageNumber };
var queryRequest = new RetrieveMultipleRequest
{
Query = response.Query
};
var result = (RetrieveMultipleResponse) _serviceContext.Execute(queryRequest);
return result.EntityCollection.Entities;
}
QueryExpression 与 Fetch XML 相比的另一个优势在于它的处理效率更高。
用户定义的视图也可以做到这一点;这些视图存储在userquery 实体中。这里唯一的区别是您不能依赖固定的视图 ID。相反,您需要根据 querytype、name、returnedtypecode、ownerid 和/或其他条件过滤您的查询。
Dynamics CRM 还有一个OrganizationRequest,允许您立即执行savedquery。但是,它以结果集 XML 字符串的形式返回其结果,因此您仍需要反序列化响应。 (可以找到一个很好的例子here。)另外,我不确定使用ExecuteByIdSavedQueryRequest时是否可以将结果集限制到特定页面:
var request = new ExecuteByIdSavedQueryRequest
{
EntityId = new Guid("00000000-0000-0000-00AA-000010001002")
};
var response = (ExecuteByIdSavedQueryResponse)serviceContext.Execute(request);
string resultset = response.String;