'给定的密钥不在字典中' - 但密钥存在

问题描述:

我目前正在开发MS Dynamics CRM 2013 - 插件。 当我尝试将字符串值分配给实体字段的键时,它给了我'keynotfound'异常。'给定的密钥不在字典中' - 但密钥存在

这让我无言以对,因为我可以验证密钥是否存在。我给出的关键字也是正确写入的,而且数据类型也是兼容的。

下面是一些额外的信息:

  • 我试图重新启动服务器解决该问题。没有。
  • 远程调试不是一个选项。
  • 我用retrieve.EntityCollection.Entities [i] [“new_name”]交换了“retrieve.EntityCollection.Entities [i] [forField]”,并且一切正常(这里指出的很明显,但是“new_name”是不是我尝试访问的关键)。
  • 停止执行@ “如果(retrieved.EntityCollection.Entities [I] [forField]的ToString()!= ”“ & &!overwriteExisting)”

有你有一个想法,以帮助我?

public void GenerateNumberForEntityCollection(string target) 
{ 
    try 
    { 
     // variables for number generation 
     bool overwriteExisting = (bool)preImageEntity["new_overwriteexisting"]; 
     int suffixstart = (int)preImageEntity["new_suffixstart"]; 
     string forField= preImageEntity["new_forfield"].ToString(); 
     string prefix = preImageEntity["new_prefix"].ToString(); 
     string postfix = preImageEntity["new_postfix"].ToString(); 
     string separator = preImageEntity["new_separator"].ToString(); 

     // Build query to get all the entries 
     RetrieveMultipleResponse retrieved; 
     int PageNumber = 1; 
     string PagingCookie = string.Empty; 
     int PageSize = 5000; 
     string[] Columns = { forField }; 
     QueryExpression query = new QueryExpression() 
     { 
      EntityName = target, 
      ColumnSet = new ColumnSet(Columns), 
      PageInfo = new PagingInfo() 
      { 
       PageNumber = 1, 
       Count = PageSize 
      } 
     }; 

     do 
     { 
      if (PageNumber != 1) 
      { 
       query.PageInfo.PageNumber = PageNumber; 
       query.PageInfo.PagingCookie = PagingCookie; 
      } 

      RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest(); 
      retrieve.Query = query; 
      retrieved = (RetrieveMultipleResponse)service.Execute(retrieve); 

      // Now that all entities are retrieved, iterate through them to gen. the numbers 
      int i = 0; 
      foreach (Entity entity in retrieved.EntityCollection.Entities) 
      { 
       if (retrieved.EntityCollection.Entities[i][forField].ToString() != "" && !overwriteExisting) 
       { 
        //continue; 
       } 
       else 
       { 
        retrieved.EntityCollection.Entities[i][forField] = prefix + separator + suffixstart.ToString() + separator + postfix; 
       } 
       suffixstart++; 
       service.Update(retrieved.EntityCollection.Entities[i]); 
       i++; 
      } 
      if (retrieved.EntityCollection.MoreRecords) 
      { 
       PageNumber++; 
       PagingCookie = retrieved.EntityCollection.PagingCookie; 
      } 
     } while (retrieved.EntityCollection.MoreRecords); 
    } 
    catch (Exception e) 
    { 
     tracing.Trace("GenerateNumberForEntityCollection: Failed: {0}", e.ToString()); 
    } 
} 

当你在Dynamics CRM中查询数据,以了解其在数据库null值是记录字段是很重要的是不包括在Attributes收集Entity实例英寸

获取从EntityAttribute值与此构造:

var value = retrieved.EntityCollection.Entities[i][forField].ToString(); 

成功时属性forField已经在数据库中的值,但失败时,其电流值null

因此,为了从一个实体获取的属性值的优选方法是GetAttributeValue<T>,这样的:当属性集合中存在的属性

var value = retrieved.EntityCollection.Entities[i].getAttributeValue<string>(forField); 

此方法返回的值,否则返回null

您是如何验证密钥是否存在的?

如果在字段中的数据为空,实体实例将不包含关键,即使你在查询的ColumnSet指定。

这将返回一个布尔值,指示该键是否存在于实体中。在尝试读取属性之前,您可以执行此控制。

var attributeExists = retrieved.EntityCollection.Entities[i].Contains(forField) 

如果字段为空,那么您所做的以下控件将会导致出现异常。只要确保该属性存在之前。

retrieved.EntityCollection.Entities[i][forField].ToString() != "" 

此外,你会得到一个空引用异常,如果没有记录是从查询返回。让你在retrieve.EntityCollection.Entities上做一个空的检查。返回

+1

我不会建议检查属性集合是否实际上包含特定成员。首选的方法是使用'GetAttribute '方法。另外,'IOrganizationService.RetrieveMultiple'返回的'DataCollection '(就像'retrieve.EntyCollection.Entities'中一样)总是存在的,因此在那里也不需要'null'检查。 –

+0

你是对的,实体永远不会为空。 – tdgtyugdyugdrugdr

如果中 任何字段(new_forfield,new_prefix,new_postfix,new_separator)具有空值, 该列不存在于检索对象和你试图让空列preImageEntity [价值“new_forfield”]将抛出keynotfound'的异常
所以更改代码

string forField= preImageEntity["new_forfield"].ToString(); 
string prefix = preImageEntity["new_prefix"].ToString(); 
string postfix = preImageEntity["new_postfix"].ToString(); 
string separator = preImageEntity["new_separator"].ToString(); 

string forField = preImageEntity.Attributes.Contains("new_forfield")? preImageEntity["new_forfield"].ToString():""; 
string prefix = preImageEntity.Attributes.Contains("new_forfield") ? preImageEntity["new_prefix"].ToString() : ""; 
string postfix = preImageEntity.Attributes.Contains("new_forfield") ? preImageEntity["new_postfix"].ToString() : ""; 
string separator = preImageEntity.Attributes.Contains("new_forfield") ? preImageEntity["new_separator"].ToString() : ""; 

这将检查现场,如果存在超过该值将解析到 串否则将指派空字符串。