问题
I'm using QueryExpression often but this far, it's been a straigh-forward get-this-from-that or put-this-in-that. Recently, I learned that there's something called LinkedEntity and I started looking for it. As an example I got inspired by a related question here on SO and I started to create an expression for getting all the members of a list given it's guid.
All the examples I've found follow the same pattern, though - as this example illustrates. From this question, I've learned that it's an obsolete approach (CRM 4.0). I've failed founding a more up-to-date example and I'm not sure how to design the linkage.
Anybody cares to provide a sample code?
Guid guid = ...;
QueryExpression request = new QueryExpression
{
EntityName = "account",
ColumnSet = new ColumnSet(true),
LinkEntities= ???, // How to link the entities correctly?
Criteria = new FilterExpression { ??? } // How to filter for *guid* only?
};
I've created a fetch-XML linking two entities but I'm not clear on how to translate it to QueryExpression entity. I've got something like this. Any suggestions?
LinkEntity linkListToMember = new LinkEntity(
"list", "listmember", "listid", "listid", JoinOperator.Natural);
LinkEntity linkMemberToContact = new LinkEntity(
"listmember", "account", "entityid", "accountid", JoinOperator.Natural);
回答1:
A Link Entity serves as your SQL Join. Use the Constructor with the from and to entity and attribute names
public LinkEntity(
string linkFromEntityName, // This is the Entity Logical Name of your Query Expression, or parent LinkEntity
string linkToEntityName, // This is the Entity Logical Name of the entity you'd like to link to
string linkFromAttributeName, // This is the attribute name on your from entity, containing your join key
string linkToAttributeName, // This is the attribute name on your to entity, containing your join key
JoinOperator joinOperator) // This is the type of Join you'd like to perform
Using the Link Entity, you can add Link Criteria to filter the results returned. You can also add Columns and return data from related entities.
Edit, an Addition to Konrad's Answer
If the 52 lines of code that Konrad lists seems too verbose, this will do the same exact thing, in 15 lines, using the extension methods defined here.
Guid guid = ...;
IOrganizationService service;
QueryExpression request = new QueryExpression("account")
{
ColumnSet = new ColumnSet("name", "region"),
};
request.Criteria.AddCondition("name", ConditionOperator.NotNull);
request.Criteria.AddCondition("region", ConditionOperator.NotNull);
var listLink = request.AddLink("listmember", "accountid", "entityid").
AddChildLink("list", "listid");
listLink.Columns.AddColumn("listname");
listLink.LinkCriteria.AddCondition("listid", ConditionOperator.Equal, guid);
回答2:
Here's a method for getting all the members of a marketing list, given that you have its guid and a server connection. What you did with the conditions is right spot on but you need to jack the one into the other. On Saturday I'll put it with a larger description on my blog.
Guid guid = ...;
IOrganizationService service;
QueryExpression request = new QueryExpression
{
EntityName = "account",
ColumnSet = new ColumnSet("name", "region"),
LinkEntities =
{
new LinkEntity
{
JoinOperator = JoinOperator.Inner,
LinkFromEntityName = "account",
LinkFromAttributeName = "accountid",
LinkToEntityName = "listmember",
LinkToAttributeName = "entityid",
LinkCriteria = { },
LinkEntities =
{
new LinkEntity
{
JoinOperator = JoinOperator.Inner,
Columns = new ColumnSet("listname"),
EntityAlias = "MarketingList",
LinkFromEntityName = "listmember",
LinkFromAttributeName = "listid",
LinkToEntityName = "list",
LinkToAttributeName = "listid",
LinkCriteria = { Conditions =
{
new ConditionExpression("listid", ConditionOperator.Equal, guid)
} }
}
}
}
},
Criteria = new FilterExpression
{
Filters =
{
new FilterExpression
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression("name", ConditionOperator.NotNull),
new ConditionExpression("region", ConditionOperator.NotNull)
}
}
}
}
};
Then, of course you need to execute the call.
EntityCollection result = service.RetrieveMultiple(request);
Finally, you might want to order and structure whatever you've got from the server. I'm using the following LINQ-to-Data expression.
IEnumerable<Member> output = result.Entities.Where(element
=> Member.IsWellFormed(element)).Select(element
=> new Member(element));
More on the subject, see the blog.
来源:https://stackoverflow.com/questions/14320701/how-to-obtain-members-of-a-marketing-list-using-queryexpression-object