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

时间:2016-04-21 14:04:08

标签: c# dynamics-crm dynamics-crm-2013 keynotfoundexception

我目前正在开发MS Dynamics CRM 2013 - 插件。 当我尝试将字符串值分配给实体字段的键时,它会给出“keynotfound”异常。

这让我一无所知,因为我可以验证密钥是否存在。我给出的密钥也写得正确,数据类型也是兼容的。

这是一些额外的信息:

  • 我尝试通过服务器重启来解决问题。什么都没有。
  • 远程调试不是一种选择。
  • 我用retrieve.EntityCollection.Entities [i] [“new_name”]交换了“retrieve.EntityCollection.Entities [i] [forField]”,一切都运行正常(有点指出明显的,但是“new_name”不是我试图访问的关键)。
  • 执行停止@“if(retrieve.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());
    }
}

3 个答案:

答案 0 :(得分:2)

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

如果字段中的数据为空,则实体实例将不包含该键,即使您在查询的ColumnSet中指定它也是如此。

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

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

如果字段为空,您已完成的控件将导致您获得的异常。只需确保该属性存在之前。

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

此外,如果没有从查询返回任何记录,您将获得空引用异常。让你对retrieve.EntityCollection.Entities进行空检查。

答案 1 :(得分:2)

当您在Dynamics CRM中查询数据时,重要的是要知道数据库中具有null值的记录字段未包含在要返回的Attributes个实例的Entity集合中

使用此结构从Entity的{​​{1}}获取值:

Attribute

在属性var value = retrieved.EntityCollection.Entities[i][forField].ToString(); 已在数据库中具有值时成功,但在其当前值为forField时失败

因此,从实体获取属性值的首选方法是null,如下所示:

GetAttributeValue<T>

此属性返回属性集合中属性存在时的值,否则返回var value = retrieved.EntityCollection.Entities[i].getAttributeValue<string>(forField);

答案 2 :(得分:1)

  

如果其中任何一个字段   (new_forfield,new_prefix,new_postfix,new_separator)具有null值,   该列未出现在检索到的对象中,并且您正在尝试获取null列的值 preImageEntity [&#34; new_forfield&#34;] 将抛出 keynotfound&#39; -exception
  所以改变代码

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() : "";  
  

这将检查字段,如果它存在,则将解析值   string else将分配空字符串。