【问题标题】:Why: LINQ to Entities does not recognize the method?为什么:LINQ to Entities 无法识别该方法?
【发布时间】:2020-04-16 10:42:29
【问题描述】:

我有两段代码,它们似乎具有相同的功能,但其中一段导致异常,而另一段则像魅力一样工作。我想知道你能想象为什么会这样吗?

我的网络应用程序中有以下行导致此异常:

LINQ to Entities 无法识别方法“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 项目更改为首先列出然后再次运行代码时,如下所示,一切顺利,不再发生异常。我想知道sn-p下面没有发生的第一个代码sn-p有什么问题?

List<DeliveryAddress> addresseList = db.DeliveryAddress.ToList(); //magic trick?!
dynamic deliveryAddresses =
    (from address in addresseList
     select filterDeliveryAddressFields(address)).ToList();

【问题讨论】:

    标签: c# linq linq-to-sql


    【解决方案1】:

    实际上,您的方法无法转换为 T-SQL,Linq to Entities 无法识别每个方法,您正在寻找的 .ToList() 方法背后的魔力是,加载数据后,任何进一步的操作(例如select)是使用 LINQ to Objects 对内存中的数据执行的。

    但是,这种方法不能保证性能,因为您必须加载 你的数据到内存中,所以想象一下你的数据库中有很多数据,接下来会发生什么?

    【讨论】:

    • 您对将所有内容加载到内存中的担忧是正确的,但是目前在这种特定情况下,我必须最终将所有内容加载到内存中,因为它们在 REST Web 服务的输出中以 JSON 形式返回。此外,作为伊朗人,我很高兴收到来自 Stackoverflow 的伊朗专家的回答。干杯!
    【解决方案2】:

    同意@Salah。在 LINQ to Entities 中,它首先尝试将您的查询转换为命令树并针对您的 ORM 执行。请阅读here您可以找到更多详细信息。

    在您的第一种方法中,Linq 尝试将您的 filterDeliveryAddressFields(address)) 方法转换为命令树。这就是为什么它抱怨LINQ to Entities does not recognize the method

    在您的第二种方法中,您针对列表或IEnumerable&lt;T&gt; 执行,这意味着您使用 LINQ to Object。你可以阅读更多关于它的信息here

    对于您的第一个解决方案,您可以尝试其他实现。只需尝试使用聚合方法来过滤您的结果。那么你就不需要filterDeliveryAddressFields(address)) 方法了。你可以找到例子here

    类似这样的东西,(对不起,我自己没有尝试过。这只是为了让你有个想法。)

    from address in db.DeliveryAddress
    select new { address.address, address.deliverTo, address.deliverToPhoneNumber, address.id };
    

    【讨论】:

      猜你喜欢
      • 2021-11-06
      相关资源
      最近更新 更多