为什么:LINQ to Entities 无法识别该方法?
Why: LINQ to Entities does not recognize the method?
我有两段代码似乎具有相同的功能,但其中一段会导致异常,而另一段却很有魅力。我想知道你能想象为什么会这样吗?
我的 Web 应用程序中有以下行导致此异常:
LINQ to Entities does not recognize the method 'System.Object
FilterDeliveryAddressFields(WebApplication1.Models.DeliveryAddress)'
dynamic deliveryAddresses = (from address in db.DeliveryAddress
select filterDeliveryAddressFields(address)).ToList();
这里是 filterDeliveryAddressFields
:
private dynamic filterDeliveryAddressFields(DeliveryAddress address)
{
return new { address.address, address.deliverTo, address.deliverToPhoneNumber, address.id };
}
这里是 Linq-2-Sql 为 DeliveryAddress
生成的模型,它与 Subscriber
:
有外键关系
public partial class DeliveryAddress
{
public int id { get; set; }
public int fkSubscriberId { get; set; }
public string address { get; set; }
public string deliverTo { get; set; }
public string deliverToPhoneNumber { get; set; }
public virtual Subscriber Subscriber { get; set; }
}
但是,当我将 db.DeliveryAddress
项更改为首先列出,然后再次 运行 编码时,一切顺利,没有再次发生异常。我想知道下面代码段中没有发生的第一个代码段有什么问题?
List<DeliveryAddress> addresseList = db.DeliveryAddress.ToList(); //magic trick?!
dynamic deliveryAddresses =
(from address in addresseList
select filterDeliveryAddressFields(address)).ToList();
实际上,您的方法无法转换为 T-SQL,Linq to Entities 无法识别所有方法,您正在寻找的 .ToList()
方法背后的魔力是,加载数据后,将使用 LINQ to Objects 对内存中已有的数据执行任何进一步的操作(例如 select
)。
但是这种方法不能保证性能,因为你必须加载
你的数据进入内存,想象一下你的数据库中有很多数据,接下来会发生什么?
同意@Salah。在 LINQ to Entities 中,它首先尝试将您的查询转换为命令树并针对您的 ORM 执行。请阅读 here 您可以找到更多详细信息。
在您的第一种方法中,Linq 尝试将您的 filterDeliveryAddressFields(address))
方法转换为命令树。这就是为什么它抱怨 LINQ to Entities does not recognize the method
.
在您的第二种方法中,您针对列表或 IEnumerable<T>
执行,这意味着您使用 LINQ to Object。您可以阅读更多相关信息 here。
对于您的第一个解决方案,您可以尝试另一种实现方式。只需尝试使用聚合方法来过滤结果。那么你不需要 filterDeliveryAddressFields(address))
方法。您可以找到示例 here
类似这样的东西,(抱歉,我自己没有尝试过。这只是为了让您了解一下。)
from address in db.DeliveryAddress
select new { address.address, address.deliverTo, address.deliverToPhoneNumber, address.id };
我有两段代码似乎具有相同的功能,但其中一段会导致异常,而另一段却很有魅力。我想知道你能想象为什么会这样吗?
我的 Web 应用程序中有以下行导致此异常:
LINQ to Entities does not recognize the method 'System.Object FilterDeliveryAddressFields(WebApplication1.Models.DeliveryAddress)'
dynamic deliveryAddresses = (from address in db.DeliveryAddress
select filterDeliveryAddressFields(address)).ToList();
这里是 filterDeliveryAddressFields
:
private dynamic filterDeliveryAddressFields(DeliveryAddress address)
{
return new { address.address, address.deliverTo, address.deliverToPhoneNumber, address.id };
}
这里是 Linq-2-Sql 为 DeliveryAddress
生成的模型,它与 Subscriber
:
public partial class DeliveryAddress
{
public int id { get; set; }
public int fkSubscriberId { get; set; }
public string address { get; set; }
public string deliverTo { get; set; }
public string deliverToPhoneNumber { get; set; }
public virtual Subscriber Subscriber { get; set; }
}
但是,当我将 db.DeliveryAddress
项更改为首先列出,然后再次 运行 编码时,一切顺利,没有再次发生异常。我想知道下面代码段中没有发生的第一个代码段有什么问题?
List<DeliveryAddress> addresseList = db.DeliveryAddress.ToList(); //magic trick?!
dynamic deliveryAddresses =
(from address in addresseList
select filterDeliveryAddressFields(address)).ToList();
实际上,您的方法无法转换为 T-SQL,Linq to Entities 无法识别所有方法,您正在寻找的 .ToList()
方法背后的魔力是,加载数据后,将使用 LINQ to Objects 对内存中已有的数据执行任何进一步的操作(例如 select
)。
但是这种方法不能保证性能,因为你必须加载 你的数据进入内存,想象一下你的数据库中有很多数据,接下来会发生什么?
同意@Salah。在 LINQ to Entities 中,它首先尝试将您的查询转换为命令树并针对您的 ORM 执行。请阅读 here 您可以找到更多详细信息。
在您的第一种方法中,Linq 尝试将您的 filterDeliveryAddressFields(address))
方法转换为命令树。这就是为什么它抱怨 LINQ to Entities does not recognize the method
.
在您的第二种方法中,您针对列表或 IEnumerable<T>
执行,这意味着您使用 LINQ to Object。您可以阅读更多相关信息 here。
对于您的第一个解决方案,您可以尝试另一种实现方式。只需尝试使用聚合方法来过滤结果。那么你不需要 filterDeliveryAddressFields(address))
方法。您可以找到示例 here
类似这样的东西,(抱歉,我自己没有尝试过。这只是为了让您了解一下。)
from address in db.DeliveryAddress
select new { address.address, address.deliverTo, address.deliverToPhoneNumber, address.id };