指定的转换无效
Specified Cast Invalid
我正在尝试为我继承的代码回顾性地编写一些单元测试。
一个特定的方法导致我在 Dynamics CRM 2011 插件方法中出现问题,在 QueryExpression
中使用 LinkedEntity
FilterCondition
实体结构
联系人 -(N:1 [查找])-> CustomEntity1 -(N:1 [查找])-> CustomEntity2
方法的目的
我正在尝试测试的方法创建了一个 QueryExpression
,它根据 CustomEntity1
的属性过滤 Contacts
,包括 LookupField
到 [=19] 的值=].
工作查询代码
为了测试我对 QueryExpression 的理解,我重写了如下代码
QueryExpression query = new QueryExpression();
query.EntityName = "contact";
query.ColumnSet = new ColumnSet(true);
query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And;
FilterExpression filter = new FilterExpression(LogicalOperator.And);
FilterExpression filter1 = new FilterExpression(LogicalOperator.Or);
filter1.Conditions.Add(new ConditionExpression("new_datefield1", ConditionOperator.Null));
filter1.Conditions.Add(new ConditionExpression("new_datefield1", ConditionOperator.LessEqual, offset));
FilterExpression filter2 = new FilterExpression(LogicalOperator.Or);
filter2.Conditions.Add(new ConditionExpression("new_datefield2", ConditionOperator.Null));
filter2.Conditions.Add(new ConditionExpression("new_datefield2", ConditionOperator.LessEqual, offset));
filter.AddFilter(filter1);
filter.AddFilter(filter2);
query.Criteria.Filters.Add(filter);
// Create the link from the contact to the CustomEntity1 entity
LinkEntity linkHistory = new LinkEntity(Contact.EntityLogicalName, new_CustomEntity1.EntityLogicalName, Contact.AttributeNames.new_CustomEntity1Lookup, new_CustomEntity1.AttributeNames.Id, JoinOperator.Inner);
linkHistory.Columns = new ColumnSet(true);
linkHistory.EntityAlias = "custEnt1";
linkHistory.LinkCriteria = new FilterExpression();
linkHistory.LinkCriteria.FilterOperator = LogicalOperator.And;
#region code added to make the test work
// Create the CustomEntity2 condition
LinkEntity linkStatus = new LinkEntity(new_CustomEntity1.EntityLogicalName, new_CustomEntity2.EntityLogicalName, new_CustomEntity1.AttributeNames.new_CustomEntity2Lookup, new_CustomEntity2.AttributeNames.Id, JoinOperator.Inner);
linkStatus.Columns = new ColumnSet(true);
linkStatus.EntityAlias = "custEnt2";
linkStatus.LinkCriteria = new FilterExpression();
linkStatus.LinkCriteria.FilterOperator = LogicalOperator.And;
linkStatus.LinkCriteria.Conditions.Add(new ConditionExpression(new_CustomEntity2.AttributeNames.Id, ConditionOperator.Equal, indStatus.Id));
linkHistory.LinkEntities.Add(linkStatus);
#endregion
//some code removed for brevity
query.LinkEntities.Add(linkHistory);
此代码 returns 一个 QueryExpression,然后用于 运行 测试,当 运行 在 FakeXrmEasy 中设置一些测试数据时测试通过。但是,我需要确保我的更改不会对当前代码和逻辑产生负面影响,因此我想在进行任何更改之前根据当前方法检查我的结果。
非工作代码
QueryExpression query = new QueryExpression();
query.PageInfo = new PagingInfo();
query.PageInfo.Count = fetchCount;
query.PageInfo.PageNumber = pageNumber;
query.PageInfo.PagingCookie = null;
// Setup the query for the contact entity
query.EntityName = Contact.EntityLogicalName;
// Specify the columns to retrieve
query.ColumnSet = new ColumnSet(true);
query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And;
FilterExpression filter1 = new FilterExpression();
filter1.FilterOperator = LogicalOperator.Or;
// Create the e2sds_lastcontactdate condition
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = Contact.AttributeNames.new_DateField1;
condition1.Operator = ConditionOperator.Null;
// Create the e2sds_lastcontactdate condition
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = Contact.AttributeNames.new_DateField1;
condition2.Operator = ConditionOperator.LessEqual;
condition2.Values.Add(offset);
FilterExpression filter2 = new FilterExpression();
filter2.FilterOperator = LogicalOperator.Or;
// Create the Last Third Party Contact condition
ConditionExpression ltpcCond1 = new ConditionExpression();
condition1.AttributeName = Contact.AttributeNames.new_DateField2;
condition1.Operator = ConditionOperator.Null;
// Create the Last Third Party Contactcondition
ConditionExpression ltpcCond2 = new ConditionExpression();
condition2.AttributeName = Contact.AttributeNames.new_DateField2;
condition2.Operator = ConditionOperator.LessEqual;
condition2.Values.Add(offset);
filter2.Conditions.AddRange(ltpcCond1, ltpcCond2);
query.Criteria.Filters.Add(filter1);
query.Criteria.Filters.Add(filter2);
// Create the link from the contact to the CustomEntity1 entity
LinkEntity linkHistory = new LinkEntity();
linkHistory.JoinOperator = JoinOperator.Natural;
linkHistory.LinkFromEntityName = Contact.EntityLogicalName;
linkHistory.LinkFromAttributeName = Contact.AttributeNames.new_CustomEntity1Lookup;
linkHistory.LinkToEntityName = new_CustomEntity1.EntityLogicalName;
linkHistory.LinkToAttributeName = new_CustomEntity1.AttributeNames.Id;
linkHistory.LinkCriteria = new FilterExpression();
linkHistory.LinkCriteria.FilterOperator = LogicalOperator.And;
#region this code throws a specified cast not valid exception
// Create the e2sds_statusid condition
ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = new_CustomEntity1.AttributeNames.new_CustomEntity2LookupField;
condition3.Operator = ConditionOperator.Equal;
condition3.Values.Add(status.Id);
#endregion
linkHistory.LinkCriteria.Conditions.Add(condition3);
//removed code for brevity
query.LinkEntities.Add(linkHistory);
我试过的
不幸的是,由于 QueryExpression
是在 RetrieveMultiple
请求中执行的,因此我无法进入代码以找出导致无效转换的数据,但是,注释掉在非工作中标记的区域代码意味着异常消失。
重写代码是一种选择 - 这就是我如何知道 TestData 作为我编写的工作 QueryExpression 代码工作的 returns 一组数据。
我目前不知道问题是出在 QueryExpression 还是 FakeXrmEasy 上,所以如果无法提供实际的解决方案,即使提供追踪问题根本原因的方法也会有所帮助。
注意:出于保密原因,自定义实体、字段和查找的名称已更改。如果名称不匹配,则可能是手动换位错误而不是代码问题。
这与crmsvcutil 生成代理类型的方式有关。不同版本之间可能存在差异。
刚刚更新了问题on GitHub
我正在尝试为我继承的代码回顾性地编写一些单元测试。
一个特定的方法导致我在 Dynamics CRM 2011 插件方法中出现问题,在 QueryExpression
LinkedEntity
FilterCondition
实体结构
联系人 -(N:1 [查找])-> CustomEntity1 -(N:1 [查找])-> CustomEntity2
方法的目的
我正在尝试测试的方法创建了一个 QueryExpression
,它根据 CustomEntity1
的属性过滤 Contacts
,包括 LookupField
到 [=19] 的值=].
工作查询代码
为了测试我对 QueryExpression 的理解,我重写了如下代码
QueryExpression query = new QueryExpression();
query.EntityName = "contact";
query.ColumnSet = new ColumnSet(true);
query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And;
FilterExpression filter = new FilterExpression(LogicalOperator.And);
FilterExpression filter1 = new FilterExpression(LogicalOperator.Or);
filter1.Conditions.Add(new ConditionExpression("new_datefield1", ConditionOperator.Null));
filter1.Conditions.Add(new ConditionExpression("new_datefield1", ConditionOperator.LessEqual, offset));
FilterExpression filter2 = new FilterExpression(LogicalOperator.Or);
filter2.Conditions.Add(new ConditionExpression("new_datefield2", ConditionOperator.Null));
filter2.Conditions.Add(new ConditionExpression("new_datefield2", ConditionOperator.LessEqual, offset));
filter.AddFilter(filter1);
filter.AddFilter(filter2);
query.Criteria.Filters.Add(filter);
// Create the link from the contact to the CustomEntity1 entity
LinkEntity linkHistory = new LinkEntity(Contact.EntityLogicalName, new_CustomEntity1.EntityLogicalName, Contact.AttributeNames.new_CustomEntity1Lookup, new_CustomEntity1.AttributeNames.Id, JoinOperator.Inner);
linkHistory.Columns = new ColumnSet(true);
linkHistory.EntityAlias = "custEnt1";
linkHistory.LinkCriteria = new FilterExpression();
linkHistory.LinkCriteria.FilterOperator = LogicalOperator.And;
#region code added to make the test work
// Create the CustomEntity2 condition
LinkEntity linkStatus = new LinkEntity(new_CustomEntity1.EntityLogicalName, new_CustomEntity2.EntityLogicalName, new_CustomEntity1.AttributeNames.new_CustomEntity2Lookup, new_CustomEntity2.AttributeNames.Id, JoinOperator.Inner);
linkStatus.Columns = new ColumnSet(true);
linkStatus.EntityAlias = "custEnt2";
linkStatus.LinkCriteria = new FilterExpression();
linkStatus.LinkCriteria.FilterOperator = LogicalOperator.And;
linkStatus.LinkCriteria.Conditions.Add(new ConditionExpression(new_CustomEntity2.AttributeNames.Id, ConditionOperator.Equal, indStatus.Id));
linkHistory.LinkEntities.Add(linkStatus);
#endregion
//some code removed for brevity
query.LinkEntities.Add(linkHistory);
此代码 returns 一个 QueryExpression,然后用于 运行 测试,当 运行 在 FakeXrmEasy 中设置一些测试数据时测试通过。但是,我需要确保我的更改不会对当前代码和逻辑产生负面影响,因此我想在进行任何更改之前根据当前方法检查我的结果。
非工作代码
QueryExpression query = new QueryExpression();
query.PageInfo = new PagingInfo();
query.PageInfo.Count = fetchCount;
query.PageInfo.PageNumber = pageNumber;
query.PageInfo.PagingCookie = null;
// Setup the query for the contact entity
query.EntityName = Contact.EntityLogicalName;
// Specify the columns to retrieve
query.ColumnSet = new ColumnSet(true);
query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And;
FilterExpression filter1 = new FilterExpression();
filter1.FilterOperator = LogicalOperator.Or;
// Create the e2sds_lastcontactdate condition
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = Contact.AttributeNames.new_DateField1;
condition1.Operator = ConditionOperator.Null;
// Create the e2sds_lastcontactdate condition
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = Contact.AttributeNames.new_DateField1;
condition2.Operator = ConditionOperator.LessEqual;
condition2.Values.Add(offset);
FilterExpression filter2 = new FilterExpression();
filter2.FilterOperator = LogicalOperator.Or;
// Create the Last Third Party Contact condition
ConditionExpression ltpcCond1 = new ConditionExpression();
condition1.AttributeName = Contact.AttributeNames.new_DateField2;
condition1.Operator = ConditionOperator.Null;
// Create the Last Third Party Contactcondition
ConditionExpression ltpcCond2 = new ConditionExpression();
condition2.AttributeName = Contact.AttributeNames.new_DateField2;
condition2.Operator = ConditionOperator.LessEqual;
condition2.Values.Add(offset);
filter2.Conditions.AddRange(ltpcCond1, ltpcCond2);
query.Criteria.Filters.Add(filter1);
query.Criteria.Filters.Add(filter2);
// Create the link from the contact to the CustomEntity1 entity
LinkEntity linkHistory = new LinkEntity();
linkHistory.JoinOperator = JoinOperator.Natural;
linkHistory.LinkFromEntityName = Contact.EntityLogicalName;
linkHistory.LinkFromAttributeName = Contact.AttributeNames.new_CustomEntity1Lookup;
linkHistory.LinkToEntityName = new_CustomEntity1.EntityLogicalName;
linkHistory.LinkToAttributeName = new_CustomEntity1.AttributeNames.Id;
linkHistory.LinkCriteria = new FilterExpression();
linkHistory.LinkCriteria.FilterOperator = LogicalOperator.And;
#region this code throws a specified cast not valid exception
// Create the e2sds_statusid condition
ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = new_CustomEntity1.AttributeNames.new_CustomEntity2LookupField;
condition3.Operator = ConditionOperator.Equal;
condition3.Values.Add(status.Id);
#endregion
linkHistory.LinkCriteria.Conditions.Add(condition3);
//removed code for brevity
query.LinkEntities.Add(linkHistory);
我试过的
不幸的是,由于 QueryExpression
是在 RetrieveMultiple
请求中执行的,因此我无法进入代码以找出导致无效转换的数据,但是,注释掉在非工作中标记的区域代码意味着异常消失。
重写代码是一种选择 - 这就是我如何知道 TestData 作为我编写的工作 QueryExpression 代码工作的 returns 一组数据。
我目前不知道问题是出在 QueryExpression 还是 FakeXrmEasy 上,所以如果无法提供实际的解决方案,即使提供追踪问题根本原因的方法也会有所帮助。
注意:出于保密原因,自定义实体、字段和查找的名称已更改。如果名称不匹配,则可能是手动换位错误而不是代码问题。
这与crmsvcutil 生成代理类型的方式有关。不同版本之间可能存在差异。
刚刚更新了问题on GitHub