我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面的微软最有价值专家(Microsoft MVP),欢迎关注我的微信公众号 MSFTDynamics365erLuoYong ,回复369或者20190923可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!
今天我测试一下,Dynamics 365 Customer Engagement V9.X版本这个问题不存在了,对于V8.X还是存在的,我至少见过两例。
我这里举个碰到的例子,有的人给实体建立字段的时候,字段的名字和实体名字相同。比如我这里测试实体的逻辑名称叫 ly_test 。
我建立了一个字段,逻辑名称也叫 ly_test。
然后我用Web API显示第一条记录,看到这个字段也在。
然后我用这个字段来构造查询条件看看,例如 $filter=ly_test eq null ,可以看到V9.X版本的Dynamics 365 Customer Engagement已经不报错了。
但是如果是V8.X会报错:
{ "error":{ "code":"","message":"Could not find a property named 'ly_test' on type 'Microsoft.Dynamics.CRM.ly_test'.","innererror":{ "message":"Could not find a property named 'ly_test' on type 'Microsoft.Dynamics.CRM.ly_test'.","type":"Microsoft.OData.Core.ODataException","stacktrace":" u5728 Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.GeneratePropertyAccessQueryForOpenType(EndPathToken endPathToken, SingleValueNode parentNode) u5728 Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.BindEndPath(EndPathToken endPathToken) u5728 Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) u5728 Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind operatorKind, QueryToken queryToken) u5728 Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken) u5728 Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) u5728 Microsoft.OData.Core.UriParser.Parsers.FilterBinder.BindFilter(QueryToken filter) u5728 Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilterImplementation(String filter, ODataUriParserConfiguration configuration, IEdmType elementType, IEdmNavigationSource navigationSource) u5728 Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilter() u5728 System.Web.OData.Query.FilterQueryOption.get_FilterClause() u5728 Microsoft.Crm.Extensibility.OData.DataQueryOptionsConverter.SetFilterExpression(QueryExpression qe, FilterQueryOption filterQueryOption) u5728 Microsoft.Crm.Extensibility.OData.QueryOptionsConverterBase`4.GetQueryExpression(ODataQueryOptions queryOptions, String edmEntityName, CrmODataExecutionContext context) u5728 Microsoft.Crm.Extensibility.OData.CrmODataServiceDataProvider.RetrieveEdmEntityCollection(CrmODataExecutionContext context, String entityCollectionName, String castedEntityName, ODataQueryOptions queryOptions) u5728 Microsoft.Crm.Extensibility.OData.EntityController.GetEntitySetInternal(String entitySetName, String castEntityName, CrmODataExecutionContext context, CrmEdmEntityObjectCollection crmEdmEntityObjectCollection, ODataQueryOptions queryOptions) u5728 Microsoft.Crm.Extensibility.OData.EntityController.GetEntitySet(String entitySetName) u5728 lambda_method(Closure , Object , Object[] ) u5728 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters) u5728 System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken) --- u5f15u53d1u5f02u5e38u7684u4e0au4e00u4f4du7f6eu4e2du5806u6808u8ddfu8e2au7684u672bu5c3e --- u5728 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() u5728 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) u5728 System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext() --- u5f15u53d1u5f02u5e38u7684u4e0au4e00u4f4du7f6eu4e2du5806u6808u8ddfu8e2au7684u672bu5c3e --- u5728 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() u5728 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) u5728 System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- u5f15u53d1u5f02u5e38u7684u4e0au4e00u4f4du7f6eu4e2du5806u6808u8ddfu8e2au7684u672bu5c3e --- u5728 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() u5728 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) u5728 System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()" } } }
你会问怎么办?其实很简单,你不用这个字段做筛选条件看下第一条就知道,原来返回的时候自动为这个与实体逻辑名称相同的字段加了一个1,也就是会变成 ly_test1,那么你做筛选的时候就要改一下名字,用 ly_test1,这样就不会有问题了。
当然如果你的系统升级的话,比如从V8.X升级到V9.X就会掉这个坑里了,V9.X已经可以了,不会自动在后面加1了,你代码不改话,使用Web API获取或者查询使用该字段就会报错。
所以我这里的忠告是,字段的名称不要和实体的名称相同!