1

Let's assume this scenario

Entity

public virtual List<Address> AddressHistory { get; set; }

public Address Address
{
    get
    {
        if (AddressHistory.Any())
        {
            return AddressHistory.OrderByDescending(x => x.CreationDate).FirstOrDefault();
        }

        return null;
    }
}

When requesting an address based on a condition, like this :

dbContext.MyEntity.Where(e => e.Address.Street == "some stuff");

I get a null reference exception.

Why ? Is there a way to make it work ?

EDIT: for those who think Address might be empty, it works when doing that :

dbContext.MyEntity.Where(e => e.AddressHistory.OrderByDescending(x => x.CreationDate).FirstOrDefault().Street == "some stuff");

EDIT: To the guy who marked it as duplicate, I don't think you understand the issue here. Please remove the marking.

So, to sum up :

If I use the getter => null exception, because the children (AdressHistory) is not lazy loaded. If I use the code inside the getters directly in the efcore expression, it works.

Which means using a getter doesn't work in EFCore.

Robouste
  • 1,731
  • 2
  • 20
  • 38

1 Answers1

6

You are right, it doesn't work. And I don't think it ever will.

EF Core currently has problems with client evaluation of navigation properties (both lazy or eager loaded). This is one of the reasons client evaluation will be removed in the next EF Core major version (3.0). And queries using such expressions will simply throw exceptions similar to EF6.

With all that in mind, don't use such "helper" properties in LINQ to Entities queries. I know this is good from OOP and reusability view, but LINQ query translation does not play well with encapsulation because it's based on knowledge and needs to see the code (expression) behind everything not part of the model mapping to the database.

You already know the working solution, simply use it. Or take a look at 3rd party extensions like NeinLinq.EntityFrameworkCore which try to address the reusability problem.

Ivan Stoev
  • 159,890
  • 9
  • 211
  • 258