我目前正在开发MS Dynamics CRM 2013 - 插件。 当我尝试将字符串值分配给实体字段的键时,它会给出“keynotfound”异常。
这让我一无所知,因为我可以验证密钥是否存在。我给出的密钥也写得正确,数据类型也是兼容的。
这是一些额外的信息:
你有没有想法帮助我?
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());
}
}
答案 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将分配空字符串。