【问题标题】:The given key was not present in the dictionary - MS CRM FetchXML字典中不存在给定的键 - MS CRM FetchXML
【发布时间】:2018-12-05 08:44:37
【问题描述】:

大量编辑:

似乎通过试图让事情变得简单来显示我让它变得更复杂的问题。

下面是完整的功能:

[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);

}

}

这里是 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>

问题是当尝试访问 sb_type(注意不是前面提到的 eventdateid)属性(确实出现在数据库中的列)时,我收到错误“字典中不存在给定的键”。因此,该列确实出现在数据库表中,并且在 fetchXML 中被引用,与在数据库中完全相同,但在调试时查看实体时,该属性未列出,与 fetchXML 中的其他属性不同,例如“sb_name”。

【问题讨论】:

  • 当您还在 fetchxml 中包含 id 属性时会发生什么?其他实体也会发生这种情况吗?你用什么代码来执行 fetch xml?
  • 如果你使用 distinct="true" 会发生什么
  • @user1515791 代码已编辑。如果我在 fetchXML 中包含 id 没有任何变化,我仍然只能返回一个属性 (sb_cpdactivityid) 和相同的错误
  • 请您发一个Minimal, Complete, and Verifiable example,清楚地显示异常发生的位置。问题不清楚。
  • 我使用了一个带有 RetrieveMultipleRequest fetchRequest1 = new RetrieveMultipleRequest { Query = new FetchExpression(xml) } 的 OrganizationServiceProxy 实例; EntityCollection returnCollection = ((RetrieveMultipleResponse)_service.Execute(fetchRequest1)).EntityCollection;所以,这可能会有所不同..

标签: c# dynamics-crm crm fetchxml


【解决方案1】:

这是 FetchXML 查询的预期行为。当您的结果集将在所有记录的列(属性)中具有NULL 值时,该属性将不会包含在EntityCollection 结果集中。

如果至少一条记录具有该列的值,则结果集将包含该列。

像这样检查并继续。

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

更新: 最佳做法是在获取null 列时处理null 的检查,如下所示 - 在访问.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();
}

【讨论】:

  • 没有真正需要 containsGetAttributeValue 检查。 GetAttributeValue 将返回 nulldefault(type)(在本例中为 Guid.Empty)。 GetAttributeValuemethod will return null or the default value for the type rather than throw an exception.
  • 我注意到只有当记录在其中一列中至少有 1 个 NULL 值时才会出现此问题。当数据库中出现 NULL 值时,如何允许?
  • @ArunVinoth 我已经进行了您建议的更改,尽管看起来应该有意义,但只要 'if(entity.GetAttributeValue("cpdactivity.sb_type") 错误仍然会发生! = null)' 被击中。就像 sb_type 不再存在于 fetchXML 中一样。
  • @Ryan 查看我的更新答案。除了 && 运算符之外,我还添加了另一个检查
  • @ArunVinoth 这行得通,谢谢。正在寻找一种处理可能具有空值的列的方法,这可以解决问题。对每个属性运行此检查是最佳做法吗?
猜你喜欢
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 2016-12-18
  • 2012-02-18
相关资源
最近更新 更多