问题
I'm trying to write a query against a WCF data service that performs a projection that includes nullable navigation properties (i.e. the FK column in the underlying data model is nullable, so the association is 0..1). The project language is VB.NET, not by my choice. Example portion of query:
From t In DataServiceReference.Context.Transactions
Where t.ID = transactionID
Select
CSM = t.WrittenByEmployee.Name, _
t.CustomerFirstName
When this query is executed against a row where WrittenByEmployee is null, I get the following error, as one would expect:
An entry returned by the navigation property 'WrittenByEmployee' is null and cannot be initialized. You should check for a null value before accessing this property.
According to this blog conditional null checking is possible in C# by using the ternary ?: operator. However, sadly the project is in VB.NET and not C#. I know that the equivalent in VB is the If() operator, but it does not appear to work as desired. If I alter the above query to this:
Select
CSM = If(t.WrittenByEmployee IsNot Nothing, t.WrittenByEmployee.Name, String.Empty)
I get this error at runtime:
Constructing or initializing instances of the type (...) with the expression (t.WrittenBy Employee != null) is not supported
I tried inverting the test but got a similar error, only with (t.WrittenByEmployee == null) instead.
How can I compose this query to check the WrittenByEmployee navigation property for nulls in a way that Data Services will accept?
回答1:
Thanks to a co-worker who pointed out that the linked blog was returning null instead of a constant when the navigation property was null!
If you change the above code to return null/Nothing when the navigation property is null, it works in C# and VB.NET!
Select
CSM = If(t.WrittenByEmployee IsNot Nothing, t.WrittenByEmployee.Name, Nothing)
^^^^^^^
来源:https://stackoverflow.com/questions/14532184/wcf-data-services-query-projection-with-nullable-navigation-properties