Your Condition Expression needs to go on the LinkCriteria object. In effect this is how your current query is getting converted.
SELECT b.Name
FROM Role b
INNER JOIN SystemUserRoles a
ON a.RoleId=b.RoleId
WHERE b.SystemUserId = '9b1bf31d-ac29-e211-9826-00155d0a0b0f'
Try this query expression:
Entity role = new Entity();
role.LogicalName = "role";
Entity systemUserRoles = new Entity();
systemUserRoles.LogicalName = "systemuserroles";
QueryExpression query = new QueryExpression() {
Distinct = false, EntityName = role.LogicalName, ColumnSet = new ColumnSet("name")
};
query.AddLink( systemUserRoles.LogicalName, "roleid", "roleid").
LinkCriteria.AddCondition("systemuserid", ConditionOperator.Equal, "9b1bf31d-ac29-e211-9826-00155d0a0b0f");
ret = _service.RetrieveMultiple(query);
Notice how a Condition is getting added to the LinkCriteria on the link rather than the query expression itself?
Update 1
As @JamesWierzba points out, there is no reason to define an entity just to use it's logical name:
QueryExpression query = new QueryExpression() {
Distinct = false, EntityName = "role", ColumnSet = new ColumnSet("name")
};
query.AddLink("systemuserroles", "roleid", "roleid").
LinkCriteria.AddCondition("systemuserid", ConditionOperator.Equal, "9b1bf31d-ac29-e211-9826-00155d0a0b0f");
ret = _service.RetrieveMultiple(query);
And if you were using the DLaB.Xrm Nuget Package you could write it even more concisely:
var qe = QueryExpressionFactory.Create("role", "name");
qe.AddLink("systemuserroles", "roleid")
.WhereEqual("systemuserid", "9b1bf31d-ac29-e211-9826-00155d0a0b0f");
ret = _service.RetrieveMultiple(qe);