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

当查询元数据时,关系看起来正确,当查询表时,会出现相关的属性链接,但是当尝试访问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数据服务的提示?

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

有一个资源集与项目有关系的项圈,所以我执行以下查询:
blah.svc/Collars(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为null。

最佳答案

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

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

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

...并且瞧瞧这个无用的空引用异常(至少在我的情况下)是由同一问题引起的。我删除了令人反感的属性(然后将其移至基本资源集,即使实际上实际上不存在该属性集)也已解决。

有趣的旁注(以防对原始海报有所帮助):ResourceType.Properties包括“基本类型”中的属性。必须更改一些代码以改为使用PropertiesDeclaredOnThisType ...

08-15 14:38