I do not fully understand why nested invokes in select do not work within LinqKit and was wondering if someone would be able to help me understand.
My problem:
First let me line out what works.
So lets say we have three db objects:
public class Customer {
public int Id {get; set;}
public string Name {get; set;}
public ICollection<Address> Addresses {get;set;}
}
public class Address {
public int Id {get;set;}
public string AddressLine {get;set;}
public int? Customer_Id { get; set; }
[ForeignKey("Customer_Id")]
public virtual Customer Customer {get; set;}
public int? Coordinates_Id { get; set; }
[ForeignKey("Coordinates_Id")]
public virtual Coordinates Coordinates {get; set;}
}
public class Coordinates {
public int Id {get;set;}
public double Latitude {get;set;}
public double Longitude {get;set;}
}
And I have three models
public class CustomerModel {
public int Id {get; set;}
public string Name {get;set;}
public AddressModel Address {get;set;}
}
public class AddressModel{
public int Id {get;set;}
public string AddressLine {get;set;}
public CoordinatesModel Coordinates {get;set;}
}
public class CoordinatesModel {
public int Id {get;set;}
public double Latitude {get;set;}
public double Longitude {get;set;}
}
So, now I want to create reusable select expressions. So I create these
public static Expression<Func<Address, AddressModel>> ToAddressModel = address =>
new AddressModel {
Id = address.Id,
AddressLine = address.AddressLine,
Coordinates = new Coordinates {
Id = address.Coordinates.Id,
Latitude = address.Coordinates.Latitude,
Longitude = address.Coordinates.Longitude
}
};
public static Expression<Func<Customer, CustomerModel>> ToCustomerModel = customer =>
new CustomerModel {
Id = customer.Id,
Name = customer.Name
Address = customer.Addresses.AsQueryable().Select(ToAddressModel).ToList()
};
And finally if I go to query this I would write
dbContext.Customers
.AsExpandable()
.Select(ToCustomerModel)
.ToList();
This works as expected. But I would like to now make CoordinatesModel more reusable and make an Expression to map it and invoke it in AddressModels Expression.
public static Expression<Func<Coordinates, CoordinatesModel>> ToCoordinates = coordinates =>
new Coordinates {
Id = coordinates.Id,
Latitude = coordinates.Latitude,
Longitude = coordinates.Longitude
}
public static Expression<Func<Address, AddressModel>> ToAddressModel = address =>
new AddressModel {
Id = address.Id,
AddressLine = address.AddressLine,
Coordinates = ToCoordinatesModel.Invoke(address.Coordinates)
};
Now if I query
dbContext.Customers
.AsExpandable()
.Select(ToCustomerModel)
.ToList();
It throws
System.NotSupportedException: LINQ to Entities does not recognize the method 'CoordinatesModel Invoke[Coordinates,Model](System.Linq.Expressions.Expression`1[System.Func`2[Coordinates,CoordinatesModel]], Coordinates)' method
This is fine if this is incorrect, I was just trying to understand why this is incorrect. If I don't invoke against a collection (like indefinite navigation properties) its fine with nested invokes.