我正在实现一个自定义数据提供程序,我已经知道它返回数据并且可以进行过滤,但是在使关系工作时遇到了一些麻烦。
查询元数据时,关系看起来是正确的,并且在查询表时会显示相关的属性链接,但在尝试访问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为空。
答案 0 :(得分:2)
好吧,在我的调试中,我注意到在错误发生之前最后一次调用GetResourceAssociationSet是针对resourceSet和resourceType参数具有不同值的情况(在派生类型的情况下)。
所以,我看了一下,发现了这个
WCF data services (OData), query with inheritance limitation?
...并且看到这个无法提供信息的空引用异常(至少在我的情况下)是由同一个问题引起的。我删除了有问题的属性(然后将其移动到基础资源集,即使它在实践中不存在),问题也解决了。
有趣的旁注(如果这有助于原始海报):ResourceType.Properties包括基本类型的属性。不得不改变一些代码来改为使用PropertiesDeclaredOnThisType ......
答案 1 :(得分:-1)
我的解决方案是我在IDataServiceQueryProvider中实现GetResourceType时犯了一个错误。
当查询作为ResourceSetReference的Resource Property时,我返回了父资源的ResourceType,而不是相关资源的类型。