如何使 CRMSvcUtil.exe 生成不重复、无错误的早期绑定选项集?
我使用 Erik Pool 的 实现ICodeWriterFilterService
和 Manny Grewal 的 GenerateOption
充当模型,过滤掉 CRMSvcUtil
生成的文件中不需要的实体。虽然 Erik 建议为 GenerateOptionSet
方法返回 true
来生成选项集的 enum
,但这样做会重复所使用的任何全局选项集。任何特定实体(如之一该帖子的评论)。
为了解决这个问题,我检查选项集是否已经生成,如果是,我返回默认选项(大多数情况下可能是 false
),如下所示。
//list of generated option sets, instantiated in the constructor
private List<string> GeneratedOptionSets;
public bool GenerateOptionSet
(OptionSetMetadataBase optionSetMetadata, IServiceProvider services)
{
if (!GeneratedOptionSets.Contains(optionSetMetadata.Name))
{
GeneratedOptionSets.Add(optionSetMetadata.Name);
return true;
}
return _defaultService.GenerateOptionSet(optionSetMetadata, services);
}
但是当将生成的文件合并到我的CRM项目中时,编译错误
无法将类型“Microsoft.Xrm.Sdk.OptionSetValue”转换为“int”
每行看起来像 的代码总是会抛出
this.SetAttributeValue
("address1_shippingmethodcode", new Microsoft.Xrm.Sdk.OptionSetValue(((int)(value))));
。
作为解决方法,我使用一个单独的项目来过滤所需的实体,使用 Erik 建议的参数运行 CRMSvcUtil
,替换代码中麻烦的部分 (int)(value)
(int)(value)文件生成后,将 value.Value
替换为 value.Value
(其中 value
是 OptionSetValue
),然后重新保存文件,所有问题都会解决离开。
我的问题是:我是否需要做一些不同的事情来使用默认的 CRMSvcUtil
生成的文件修复此编译错误,而不需要做一些像更改生成的文件这样的黑客行为?
I use Erik Pool's implementation of ICodeWriterFilterService
and Manny Grewal's GenerateOption
function as a model to filter out unwanted entities in the file that CRMSvcUtil
generates. While Erik recommends returning true
for the GenerateOptionSet
method to generate enums
for option sets, doing so duplicates any of the global option sets that are used by any particular entity (as mentioned in one of the comments on that post).
To address this, I check to see if the option set has been already generated, and if so, I return the default option (presumably false
for most cases) as in the below.
//list of generated option sets, instantiated in the constructor
private List<string> GeneratedOptionSets;
public bool GenerateOptionSet
(OptionSetMetadataBase optionSetMetadata, IServiceProvider services)
{
if (!GeneratedOptionSets.Contains(optionSetMetadata.Name))
{
GeneratedOptionSets.Add(optionSetMetadata.Name);
return true;
}
return _defaultService.GenerateOptionSet(optionSetMetadata, services);
}
But when incorporating the generated file in my CRM projects, the compilation error
Cannot convert type 'Microsoft.Xrm.Sdk.OptionSetValue' to 'int'
is always thrown by every line of code that looks like
this.SetAttributeValue
("address1_shippingmethodcode", new Microsoft.Xrm.Sdk.OptionSetValue(((int)(value))));
.
As a workaround, I use a separate project where I filter the entities I need, run CRMSvcUtil
with the arguments Erik suggests, replace the troublesome part of the code (int)(value)
(where value
is an OptionSetValue
) with value.Value
after the file is generated, and then resave the file, and all issues go away.
My question is this: do I need to do something differently that will fix this compilation error with the default CRMSvcUtil
generated file without doing something so hackish as altering that generated file?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用
ICustomizeCodeDomService
接口重写选项集的SetAttributeValue
方法。下面的片段:}
You can use the
ICustomizeCodeDomService
interface to rewrite theSetAttributeValue
method for the optionSets. Snippet below:}
UpdateEnumSetter 方法的一些更改:
Some changes to the UpdateEnumSetter method:
我敢打赌 Guarav 的答案是真正的方法,但由于缺乏有关
CRMSvcUtil
的文档,我被迫使用我的解决方法。 (我使用一个单独的项目,在其中过滤我需要的实体,使用 Erik 建议的参数运行CRMSvcUtil
,替换代码中麻烦的部分(int)(value)
(其中value
是一个OptionSetValue
),在文件生成后使用value.Value
,然后重新保存文件。)这不是一个完美的解决方案,但是它一直在研究我研究过的几个样本到目前为止。
I'm betting that Guarav's answer is the real way to go, but in the absence of documentation surrounding
CRMSvcUtil
, I'm forced to use my workaround. (I use a separate project where I filter the entities I need, runCRMSvcUtil
with the arguments Erik suggests, replace the troublesome part of the code(int)(value)
(wherevalue
is anOptionSetValue
) withvalue.Value
after the file is generated, and then resave the file.)Not a perfect solution, but it's been working on the few samples I've worked with so far.
事实证明,此错误与当类型可供使用时尝试创建如下代码所示的选项集的代码有关。请注意,唯一的区别是为返回类型和强制转换选择了正确的类型。
应该可以更新codegen的东西来修复这个错误,但是最好让微软正确地修复这个该死的东西,我会制定一个解决方案,但我真的没有时间现在就实现它,因为即使我们必须处理 optionssetvalue 类,我们也有一个基本有效的解决方案。
It turns out that this fault is to do with the code attempting to make optionsets that look like the code below when the types are available for use. Note the only difference is the correct type being chose for the return type and the cast.
It should be possible to update the codegen stuff to fix this bug, but it might be better to get microsoft to fix the damn thing properly, I would make a solution but I don't really have time to implement it right now because we have a mostly working solution even if we have to deal with the optionsetvalue class.
我终于能够生成带有一组经过过滤的实体和无错误选项集的早期绑定类。我通过这个帖子找到了大部分答案,所以谢谢大家。但问题是很难将所有各种建议编译成实际......编译的东西。所以我想我应该为了其他人的利益发布我的最终解决方案,这对我有用。
我使用 Erik Pool、Manny Grewal 和 Peter Majeed 的解决方案仅输出具有正确值的不同枚举,然后将其与 Gaurav Dalal 的解决方案(由 JFK007 更新以修复转换错误)结合起来重写
SetAttributeValue
导致了(int)(value)
错误。作为额外的好处,我使用相同的解决方案来过滤不同的选项集,同时也过滤不同的选项集值(这是我的组织中的一个问题)。结果是一个包含
CodeWriterFilter
和CustomizeCodeDomService
的类库、用于运行CrmSvcUtil.exe
的 cmd 批处理文件以及filter.xml
来过滤实体。在类库中添加对
CrmSvcUtil.exe
、Microsoft.Xrm.Sdk
和System.Runtime.Serialization
的引用,然后编译 dll 并复制将其复制到与CrmSvcUtil.exe
相同的文件夹中。使用我包含的命令来引用您的新程序集并构建早期绑定的类文件。CodeWriterFilter
:CustomizeCodeDomService
:CrmSvcUtil_run.cmd
命令批处理文件:filter.xml
I finally am able to generate early bound class with a filtered set of entities and error free option set. I found the bulk of my answer through this thread, so thanks guys. The problem though is it's difficult to compile all of the various suggestions into something that actually... compiles. So I thought I'd post my final solution for the benefit of others, here's what worked for me.
I used Erik Pool's, Manny Grewal's, and Peter Majeed's solution for outputting only distinct enums with proper values, then combined that with Gaurav Dalal's solution (updated by JFK007 to fix the cast error) to re-write the
SetAttributeValue
that caused the(int)(value)
error. And as an added bonus, I used the same solution for filtering distinct option sets to also filter for distinct option set values (which was an issue in my org).The result is a class library containing
CodeWriterFilter
andCustomizeCodeDomService
, the cmd batch file to runCrmSvcUtil.exe
, and thefilter.xml
to filter the entities.In your class library add references to
CrmSvcUtil.exe
,Microsoft.Xrm.Sdk
, andSystem.Runtime.Serialization
then compile the dll and copy it to the same the folder as yourCrmSvcUtil.exe
. Use the command I've included to reference your new assembly and build the early bound class file.CodeWriterFilter
:CustomizeCodeDomService
:CrmSvcUtil_run.cmd
Command Batch File:filter.xml
crmsrvcutil 中似乎存在一个错误,现已修复。我的 OptionSet 属性代码现在如下所示:
设置 OptionSetValue 时没有错误...
It looks like there was a bug in the crmsrvcutil that has since been fixed. My code for OptionSet properties now looks like this:
And I get no error setting the OptionSetValue...