涉及空外键
的查询中的NullReferenceException我有一个VB项目,它使用odata服务和linq查询。 (上一句话充满了我之前从未做过的事情,所以这可能会变得粗糙。)
有一个"员工"表和"应用程序"表,以1对1的关系链接。我试图弄清楚如何利用这种关系来加入表并从每个表中查询一个字段。
此查询是我最接近的(它编译,与我尝试的其他变体不同):
Dim Emps = (From e In ctx.Employees Select e.FirstName, e.Application.AppNo)
我甚至可以检查结果中有多少条记录:
Console.WriteLine(Emps.Count)
得到一个合理的数字。但是,任何尝试对结果执行任何其他操作都会导致抛出异常。简而言之,我这样做了:
Console.WriteLine("----")
Console.WriteLine(Emps.FirstOrDefault.FirstName)
Console.WriteLine("====")
它扔了:
Unhandled Exception: System.NullReferenceException: An entry returned by the navigation property 'Application' is null and cannot be initialized. You should check for a null value before accessing this property.
at System.Data.Services.Client.Materialization.ODataEntityMaterializer.CheckEntryToAccessNotNull(MaterializerEntry entry, String name)
at System.Data.Services.Client.Materialization.ODataEntityMaterializer.ProjectionValueForPath(MaterializerEntry entry, Type expectedType, ProjectionPath path)
at System.Data.Services.Client.Materialization.ODataEntityMaterializerInvoker.ProjectionValueForPath(Object materializer, Object entry, Type expectedType, Object path)
at _dynamic_ODataEntityMaterializerInvoker_ProjectionValueForPath(Object , Object , Type , Object )
at lambda_method(Closure , Object , Object , Type )
at System.Data.Services.Client.ProjectionPlan.Run(ODataEntityMaterializer materializer, ODataEntry entry, Type expectedType)
at System.Data.Services.Client.Materialization.ODataEntityMaterializer.ReadImplementation()
at System.Data.Services.Client.MaterializeAtom.MoveNextInternal()
at System.Data.Services.Client.MaterializeAtom.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__1`1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Data.Services.Client.DataServiceQueryProvider.ReturnSingleton[TElement](Expression expression)
at System.Data.Services.Client.DataServiceQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at odata.Odata.Main() in H:\Visual Studio 2015\Projects\odata\odata\Odata.vb:line 52
请注意,即使我只是尝试打印其他字段,我也得到了关于null应用程序的异常,这与Application无关,我觉得这很奇怪。例外发生在&#34; ----&#34;是在#34; ====&#34;之前打印的。
我猜至少有一个记录(没有应用程序的Employee)中有一个空外键。在这种情况下,我想为e.Application.AppNo设置一个空字符串或其他占位符值,但我无法弄清楚如何告诉它这样做。
在更类似SQL的语法中,它将是
FROM Employees e
SELECT
e.FirstName,
CASE WHEN e.Application IS NOT NULL
THEN e.Application.AppNo
ELSE ''
END AS AppNo
但是所有将其转换为vb / linq语句的尝试都会导致语法错误。
我可能不太了解架构。我在linq中使用显式连接语法看到了其他问题,但我不知道如何在这里做到这一点,因为我不知道外键字段实际调用了什么;我所知道的是odata魔法中有一些东西让我使用e.Application.foo
,其中foo
是Application表中的一个字段,e
是一个Employees记录。
odata服务提供商提供的文档质量非常低。 (VB中的简短代码示例,提供截屏不是文本; HTTP请求的完整转储和对应于示例查询的响应,包括一个超过50页的XML响应;以及关于身份验证的主题,对HTTP Basic&的引用#34; RCF&#34)
更新
Mark的建议产生了一个新例外:
Unhandled Exception: System.NotSupportedException: Constructing or initializing instances of the type VB$AnonymousType_0`2[System.String,System.Object] with the expression (e.Application != null) is not supported.
at System.Data.Services.Client.ProjectionAnalyzer.NonEntityProjectionAnalyzer.VisitBinary(BinaryExpression b)
at System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.ALinqExpressionVisitor.VisitConditional(ConditionalExpression c)
at System.Data.Services.Client.ProjectionAnalyzer.NonEntityProjectionAnalyzer.VisitConditional(ConditionalExpression c)
at System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.ALinqExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at System.Data.Services.Client.ALinqExpressionVisitor.VisitNew(NewExpression nex)
at System.Data.Services.Client.ProjectionAnalyzer.NonEntityProjectionAnalyzer.VisitNew(NewExpression nex)
at System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.ProjectionAnalyzer.NonEntityProjectionAnalyzer.Analyze(Expression e, PathBox pb, DataServiceContext context)
at System.Data.Services.Client.ProjectionAnalyzer.Analyze(LambdaExpression e, PathBox pb, DataServiceContext context)
at System.Data.Services.Client.ProjectionAnalyzer.AnalyzeResourceExpression(LambdaExpression lambda, ResourceExpression resource, DataServiceContext context)
at System.Data.Services.Client.ProjectionAnalyzer.Analyze(LambdaExpression le, ResourceExpression re, Boolean matchMembers, DataServiceContext context)
at System.Data.Services.Client.ResourceBinder.AnalyzeProjection(MethodCallExpression mce, SequenceMethod sequenceMethod, Expression& e)
at System.Data.Services.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce)
at System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.ALinqExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at System.Data.Services.Client.ALinqExpressionVisitor.VisitMethodCall(MethodCallExpression m)
at System.Data.Services.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce)
at System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.DataServiceALinqExpressionVisitor.Visit(Expression exp)
at System.Data.Services.Client.ResourceBinder.Bind(Expression e, DataServiceContext context)
at System.Data.Services.Client.DataServiceQueryProvider.Translate(Expression e)
at System.Data.Services.Client.DataServiceQuery`1.QueryComponents(ClientEdmModel model)
at System.Data.Services.Client.DataServiceRequest.GetQuerySetCount(DataServiceContext context)
at System.Data.Services.Client.DataServiceQueryProvider.ReturnSingleton[TElement](Expression expression)
at System.Data.Services.Client.DataServiceQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
at odata.Odata.Main() in H:\Visual Studio 2015\Projects\odata\odata\Odata.vb:line 51
这是在尝试打印Emps.Count