I've been converting some of my CRM4.0 plugins to use the CRM2011 SDK. I'm just starting to work with LINQ for Early-Bound entities and have come across a problem.
I am trying to get the formatted value of an OptionSetValue in a joined entity. After looking at this MSDN SDK Query Example, I managed to retrieve the formatted values for the primary entity, but can't seem to translate that to a joined entity.
The code below is a sample of what I'm trying to achieve. I started by using the code from the SDK example.
var query_join8 = (from a in sContext.AccountSet
join c in sContext.ContactSet
on a.PrimaryContactId.Id equals c.ContactId
into gr
from c_joined in gr.DefaultIfEmpty()
select new
{
contact_name = c_joined.FullName,
account_name = a.开发者_开发问答Name,
account_addresstypecode = a.Address1_AddressTypeCode,
account_addresstypename = a.FormattedValues.ContainsKey("address1_addresstypecode") ? a.FormattedValues["address1_addresstypecode"] : null,
account_formattedValues = a.FormattedValues,
contact_addresstypecode = c_joined.Address1_AddressTypeCode,
contact_addresstypename = c_joined.FormattedValues.ContainsKey("address1_addresstypecode") ? c_joined.FormattedValues["address1_addresstypecode"] : null,
contact_formattedValues = c_joined.FormattedValues,
}).ToArray();
The account_formattedValues and account_addresstypename come across corrected and I have access to that data, but for some reason the contact_formattedValues item contains an empty collection, and thus contact_addresstypename is null.
Am I doing this incorrectly, or have I missed something? Has anyone been able or knows how to achieve this? Any help is greatly appreciated.
There is a bug in the LINQ query provider where the formatted values are not properly applied to the entities following the first entity. It is related to how the QueryExpression API (which the LINQ provider uses) handles join queries. It does so by pooling all the attributes and formatted values in the first/primary entity (technically the only entity). It then uses a set of "link aliases" to categorize these values. We can exploit this as a workaround to the missing FormattedValues.
var acs =
from a in context.AccountSet
join c in context.ContactSet on a.PrimaryContactId.Id equals c.ContactId
into gr
from c_joined in gr.DefaultIfEmpty()
select new
{
account_addresstypecode = a.Address1_AddressTypeCode,
account_addresstypename = a.FormattedValues["address1_addresstypecode"],
contact_addresstypecode = c_joined.Address1_AddressTypeCode,
contact_addresstypename = a.FormattedValues["c_0.address1_addresstypecode"],
a.FormattedValues
};
foreach (var ac in acs)
{
foreach (var pair in ac.FormattedValues)
{
Console.WriteLine("{0} {1}", pair.Key, pair.Value);
}
}
Notice all the label values are pulled from the "a" parameter, The tricky part is knowing what the alias/prefix value is (for the non-primary entities) which is a dynamically created string based on the name of the entity-set parameter, "c", and a counter value. This can be inspected by dumping the FormattedValues of the primary entity.
精彩评论