Given this model:
```
public class Thing
{
public int Id { get; set; }
public string Name { get; set; }
public Person Owner { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class TownContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Thing> Things { get; set; }
}
}
```
For a query setup like this:
```
var thingStub = new Thing { Id = 1 };
db.People.FirstOrDefault(p => p.Id == thingStub.Owner.Id);
```
A NullReferenceException is expected because thingStub.Owner is null. However because we are now using reflection to evaluate the expression thingStub.Owner.Id, the user gets a TargetException with the message 'Non-static method requires a target'. We should consider throwing a NullReferenceException in this situation as it is a more clear symptom of a coding error that needs to be corrected.
One possible fix would be to resort to the old method of compiling the LINQ expression for the property access into a delegate that we can invoke if the TargetException is detected.
Stack trace:
```
System.Reflection.TargetException: Non-static method requires a target.
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryGetFieldOrPropertyValue(MemberExpression me, Object instance, Object& memberValue)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryEvaluatePath(Expression expression, ConstantExpression& constantExpression)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.EvaluateParameter(Object[] arguments)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery.ToTraceString()
at System.Data.Entity.Internal.Linq.InternalQuery`1.ToString()
at System.Data.Entity.Infrastructure.DbQuery`1.ToString()
at ConsoleApplication20.Program.Main(String[] args) in ...
```
```
public class Thing
{
public int Id { get; set; }
public string Name { get; set; }
public Person Owner { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class TownContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Thing> Things { get; set; }
}
}
```
For a query setup like this:
```
var thingStub = new Thing { Id = 1 };
db.People.FirstOrDefault(p => p.Id == thingStub.Owner.Id);
```
A NullReferenceException is expected because thingStub.Owner is null. However because we are now using reflection to evaluate the expression thingStub.Owner.Id, the user gets a TargetException with the message 'Non-static method requires a target'. We should consider throwing a NullReferenceException in this situation as it is a more clear symptom of a coding error that needs to be corrected.
One possible fix would be to resort to the old method of compiling the LINQ expression for the property access into a delegate that we can invoke if the TargetException is detected.
Stack trace:
```
System.Reflection.TargetException: Non-static method requires a target.
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryGetFieldOrPropertyValue(MemberExpression me, Object instance, Object& memberValue)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryEvaluatePath(Expression expression, ConstantExpression& constantExpression)
at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.EvaluateParameter(Object[] arguments)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery.ToTraceString()
at System.Data.Entity.Internal.Linq.InternalQuery`1.ToString()
at System.Data.Entity.Infrastructure.DbQuery`1.ToString()
at ConsoleApplication20.Program.Main(String[] args) in ...
```