LinqKit嵌套调用:“LINQ to Entities不识别方法'Invoke'”

3

我不太理解为什么LinqKit中的select嵌套调用不起作用,希望有人能帮助我理解。

我的问题是:

首先让我列出有效的部分。

假设我们有三个数据库对象:

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;}
}

我有三个模型

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;}
}

现在,我想要创建可重用的选择表达式。因此,我创建了这些内容:

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()
     };

最后,如果我要查询这个内容,我会写

 dbContext.Customers
    .AsExpandable()
    .Select(ToCustomerModel)
    .ToList();

这个代码可以如预期地运行。但是我希望现在能够使CoordinatesModel变得更加可复用,并创建一个表达式来映射它,并在AddressModels表达式中调用它。
  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)
     };

现在,如果我查询

  dbContext.Customers
    .AsExpandable()
    .Select(ToCustomerModel)
    .ToList();

它抛出异常

  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

如果这不正确,那没关系,我只是想了解为什么不正确。如果我没有针对集合(如不确定的导航属性)进行调用,嵌套调用就没问题。


如果有人看到这个,我应该补充一下提供程序是Npgsql。 - GrizzlyEnglish
1个回答

0

你必须明确告诉linq,你正在扩展子表达式 - 就像在使用.AsExpandable()时一样 - 当调用子集时,你必须扩展父级以遍历树并扩展子表达式。

所以...你只需要在父表达式中添加一个Expand,在这种情况下。

public static Expression<Func<Customer, CustomerModel>> ToCustomerModel = customer =>
     new CustomerModel {
       Id = customer.Id,
       Name = customer.Name
       Address = customer.Addresses.AsQueryable().Select(ToAddressModel.Expand()).ToList()
     };

导航属性没问题,因为当您展开其父级时,它将拉入所有子表达式以便展开表达式 - 但选择(我只能假设是另一个投影)除非明确说明,否则不会进行。

这里是文档:http://www.albahari.com/nutshell/linqkit.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接