简体   繁体   中英

The given key was not present in the dictionary - MS CRM FetchXML

HUGE EDIT:

It seems through trying to make things simple to show the issue I was making it more complicated.

Here is the full function in action:

[AllowAnonymous]
[HttpGet]
public HttpResponseMessage getCPDActiviesByMemberNumber(int memberNumber) {

List<Entity> sourceData = null;
List<CPDActivity> membersActivites = new List<CPDActivity>();
List<member> memberRecords = new List<member>();

try {

    string xmlFile = "";
    string memberNumberString = memberNumber.ToString();
    xmlFile = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + @"_Code\Fetch\MembersActivities.xml");
    xmlFile = String.Format(xmlFile, memberNumberString);
    OrganizationServiceClient crm = new OrganizationServiceClient();
    sourceData = crm.GetEntities(xmlFile);

    if (sourceData.Count > 0) {

        member member = new member();

        foreach (Entity entity in sourceData) {

            CPDActivity cpdActivity = new CPDActivity();

            // sb_membership
            member.ID = entity.GetAttributeValue<Guid>("sb_membershipid");
            member.MemberNumber = entity.GetAttributeValue<String>("sb_membershipno");
            member.ContactID = entity.GetAttributeValue<EntityReference>("sb_contactid").Id.ToString(); ;
            member.MembershipStatus = entity.FormattedValues["statuscode"].ToString();
            member.MemberGrade = entity.GetAttributeValue<String>("sb_name");
            member.StartDate = entity.GetAttributeValue<DateTime>("sb_startdate").ToString();
            member.ExpiryDate = entity.GetAttributeValue<DateTime>("sb_expirydate").ToString();
            // contact (membercontact)
            member.Title = entity.FormattedValues["membercontact.sb_title"].ToString();
            member.FirstName = entity.GetAttributeValue<AliasedValue>("membercontact.firstname").Value.ToString();
            member.LastName = entity.GetAttributeValue<AliasedValue>("membercontact.lastname").Value.ToString();
            member.RegionCode = entity.GetAttributeValue<AliasedValue>("membercontact.sb_regioncode").Value.ToString();
            member.Email = entity.GetAttributeValue<AliasedValue>("membercontact.emailaddress1").Value.ToString();
            // contact (membercontact) - sb_cpdactivity (cpdactivity) 
            member.Region = entity.GetAttributeValue<AliasedValue>("region.sb_name").Value.ToString();
            // sb_cpdactivity (cpdactivity)
            cpdActivity.ActivityName = entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_name").Value.ToString();
            cpdActivity.CreatedOn = (DateTime)entity.GetAttributeValue<AliasedValue>("cpdactivity.createdon").Value;
            cpdActivity.CpdHours = Convert.ToSingle(entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_cpdhours").Value);
            cpdActivity.ActivityDate = (DateTime)entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_activitydate").Value;
            cpdActivity.StatusCode = entity.FormattedValues["cpdactivity.statuscode"].ToString();
            cpdActivity.CpdActivityID = (Guid)entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_cpdactivityid").Value;
            cpdActivity.MemberContactID = ((EntityReference)entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_membercontactid").Value).Id;
            //
            cpdActivity.EventType = entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_type").Value.ToString();  // <<<<< problem here
            cpdActivity.EventType = entity.FormattedValues["cpdactivity.sb_type"].ToString();  // <<<<< problem here
            //
            member.Activities.Add(cpdActivity);
            memberRecords.Add(member);
        }

        return Request.CreateResponse(HttpStatusCode.OK, memberRecords);

    } else {

        return Request.CreateResponse(HttpStatusCode.OK, "getCPDActiviesByMemberId " + "no records found");

    }

} catch (Exception ex) {

    string error = ex.Message.ToString();
    string errors = error;
    return Request.CreateResponse(HttpStatusCode.OK, "getMembers - error : " + error);

}

}

And here is the FetchXML:

<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
  <entity name="sb_membership">
    <attribute name="sb_contactid" />
    <attribute name="sb_name" />
    <attribute name="sb_membershipno" />
    <attribute name="sb_expirydate" />
    <attribute name="sb_startdate" />
    <attribute name="statuscode" />
    <attribute name="sb_membershipid" />
    <order attribute="sb_name" descending="false" />
    <filter type="and">
      <condition attribute="statecode" operator="eq" value="0" />
      <condition attribute="sb_membershipno" operator="eq" value='{0}' />
    </filter>
    <link-entity name="contact" from="contactid" to="sb_contactid" visible="false" link-type="outer" alias="membercontact">
      <attribute name="sb_title" />
      <attribute name="lastname" />
      <attribute name="firstname" />
      <attribute name="mobilephone" />
      <attribute name="emailaddress1" />
      <attribute name="sb_regioncode" />
      <link-entity name="sb_geographicregion" from="sb_regioncode" to="sb_regioncode" link-type="outer" alias="region">
        <attribute name="sb_name" />
      </link-entity>
    </link-entity>
    <link-entity name="sb_cpdactivity" from="sb_membercontactid" to="sb_contactid" visible="false" link-type="outer" alias="cpdactivity">
      <attribute name="sb_cpdactivityid" />
      <attribute name="sb_membercontactid" />
      <attribute name="sb_name" />
      <attribute name="sb_type" />
      <attribute name="createdon" />
      <attribute name="sb_activitydate" />
      <attribute name="statuscode" />
      <attribute name="sb_cpdhours" />
    </link-entity>
  </entity>
</fetch>

The problem is when trying to get to the sb_type (note not eventdateid as mentioned previously) attribute (a column which does appear in the database) I get the error "The given key was not present in the dictionary." So the column DOES appear in the database table and is referenced in the fetchXML exactly as it is in the database but when looking at the entity while debugging the attribute is not listed unlike others in the fetchXML such as 'sb_name'.

This is expected behavior of FetchXML query. When your resultset is going to have NULL value in a column (attribute) for all the records, then that attribute will not be included in EntityCollection resultset.

If atleast one record is having value for that column, then the resultset will include that column.

Do a check like this & continue.

var thing;
if(entity.Contains("sb_eventdateid")){
    thing = entity.GetAttributeValue<Guid>("sb_eventdateid");
}

Update : It's best practice to handle the null check like below when you are getting null columns - before accessing .Value

if(entity.Attributes.Contains("cpdactivity.sb_type") && entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_type") != null)
{
            cpdActivity.EventType = entity.GetAttributeValue<AliasedValue>("cpdactivity.sb_type").Value.ToString();  
            cpdActivity.EventType = entity.FormattedValues["cpdactivity.sb_type"].ToString();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM