自定义wcf数据提供程序并调试关系错误

时间:2011-10-05 08:11:53

标签: wcf wcf-data-services

我正在实现一个自定义数据提供程序,我已经知道它返回数据并且可以进行过滤,但是在使关系工作时遇到了一些麻烦。

查询元数据时,关系看起来是正确的,并且在查询表时会显示相关的属性链接,但在尝试访问ResourceReference属性时,我会收到以下异常:

    Object reference not set to an instance of an object.
        System.NullReferenceException
        stacktrace at System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceAssociationSet(ResourceSetWrapper resourceSet, ResourceType resourceType, ResourceProperty resourceProperty)
   at System.Data.Services.Providers.DataServiceProviderWrapper.GetContainer(ResourceSetWrapper sourceContainer, ResourceType sourceResourceType, ResourceProperty navigationProperty)
   at System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceProperties(ResourceSetWrapper resourceSet, ResourceType resourceType)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteObjectProperties(IExpandedResult expanded, Object customObject, ResourceType resourceType, Uri absoluteUri, String relativeUri, SyndicationItem item, DictionaryContent content, EpmSourcePathSegment currentSourceRoot)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteEntryElement(IExpandedResult expanded, Object element, ResourceType expectedType, Uri absoluteUri, String relativeUri, SyndicationItem target)
   at System.Data.Services.Serializers.SyndicationSerializer.WriteTopLevelElement(IExpandedResult expanded, Object element)
   at System.Data.Services.Serializers.Serializer.WriteRequest(IEnumerator queryResults, Boolean hasMoved)
   at System.Data.Services.ResponseBodyWriter.Write(Stream stream)

以下是我如何创建关系的示例:

var sourceReference = new ResourceProperty(
                relatedType.ResourceTypeName,
                ResourcePropertyKind.ResourceReference,
                relatedType.ResourceType);
            sourceReference.CanReflectOnInstanceTypeProperty = false;
            compoundType.ResourceType.AddProperty(sourceReference);

var destinationReference = new ResourceProperty(
                compoundType.ResourceSetName,
                ResourcePropertyKind.ResourceSetReference,
                compoundType.ResourceType);
            destinationReference.CanReflectOnInstanceTypeProperty = false;
            source.ResourceType.AddProperty(destinationReference);

var sourceAssociation = new ResourceAssociationSet(
                        "source",
                        new ResourceAssociationSetEnd(compoundType.ResourceSet, compoundType.ResourceType, sourceReference),
                        new ResourceAssociationSetEnd(relatedType.ResourceSet, relatedType.ResourceType, null));

var destinationAssociation = new ResourceAssociationSet(
                             "destination",
                             new ResourceAssociationSetEnd(relatedType.ResourceSet, relatedType.ResourceType, destinationReference),
                             new ResourceAssociationSetEnd(compoundType.ResourceSet, compoundType.ResourceType, null));

通过查看OData网站上的示例代码,我认为我已经完成了所有操作,并且无法确定我的错误。有任何想法吗?或有关调试自定义WCF数据服务的提示?

更新 这是在零异常之前发生的事情。

有一个资源集Collars与Projects有关系,所以我做这个查询: blah.svc /项圈(1)/项目

我的IDataServiceMetadataProvider中的GetResourceAssociationSet覆盖使用参数ResourceSet = Collars,ResourceType = Collar,Property = Project进行调用,并返回上面指定的关联集。 然后使用ResourceSet = Projects,ResourceType = Collar,Property = Project再次调用GetResourceAssociationSet,并返回相同的关联集。

然后在System.Data.Services.Providers.GetResourceAssociationSetEnd中传入的变量是resourceSet = Projects,resourceType = Collar,resourceProperty = Project,此函数返回null。

这使得System.Data.Services.Providers.DataServiceProviderWrapper.GetResourceAssociationSet中的thisEnd等于null。 然后使用相同的变量调用GetRelatedResourceAssociationSetEnd,并返回null。

然后随着电话

崩溃
ResourceSetWrapper relatedSet = this.ValidateResourceSet(relatedEnd.ResourceSet); 

因为relatedEnd为空。

2 个答案:

答案 0 :(得分:2)

好吧,在我的调试中,我注意到在错误发生之前最后一次调用GetResourceAssociationSet是针对resourceSet和resourceType参数具有不同值的情况(在派生类型的情况下)。

所以,我看了一下,发现了这个

WCF data services (OData), query with inheritance limitation?

...并且看到这个无法提供信息的空引用异常(至少在我的情况下)是由同一个问题引起的。我删除了有问题的属性(然后将其移动到基础资源集,即使它在实践中不存在),问题也解决了。

有趣的旁注(如果这有助于原始海报):ResourceType.Properties包括基本类型的属性。不得不改变一些代码来改为使用PropertiesDeclaredOnThisType ......

答案 1 :(得分:-1)

我的解决方案是我在IDataServiceQueryProvider中实现GetResourceType时犯了一个错误。

当查询作为ResourceSetReference的Resource Property时,我返回了父资源的ResourceType,而不是相关资源的类型。