如何在LINQ lambda扩展方法中插入方法

本文关键字:方法 插入 扩展 lambda LINQ | 更新日期: 2023-09-27 18:28:25

我必须在LINQ lambda中放置一个方法。我有以下代码:

string productName = "Some product";
searchShoppingCart = shoppingCart.Where(m => productName.Equals(_ProductRepository.GetProductName(m.Id)));

基本上,此代码用于选择包含productName的所有shoppingCart实例。

方法string GetProductName(int shoppingCartId)是来自_ProductRepository的返回一个产品名称的方法。如何实现此方法及其逻辑并不重要。

问题是LINQ抛出了一个异常。我知道引发此异常的原因,我只是想知道一个变通方法。我试过

var productContained = shoppingCart.Select(sc => new
                    {
                        scId = sc.Id,
                        productName = _ProductRepository.GetProductName(sc.Id)
                    });
searchShoppingCart = shoppingCart.Where(sc => sc.Id.Equals(productContained.Where(pc => pc.productName.Equals(productName))
                                                                           .Select(pc => pc.Id)));

但它给了我同样的例外。还有其他变通办法吗?

更新

抛出的异常是

LINQ to Entities无法识别方法"System.String GetProductName(Int32)"方法,并且此方法无法转换为存储表达式

如何在LINQ lambda扩展方法中插入方法

它抛出一个异常,因为它试图将代码转换为SQL(但它做不到)。阅读本文了解一些解决方法:http://thoai-nguyen.blogspot.it/2011/05/custom-function-entity-framework.html

如果您正在使用IQueryable(我相信您确实这样做了),则对自定义.NET方法的调用无法转换为查询-这就是您出现异常的原因。

解决方法是提取所有可能的购物车,然后将您的方法应用于内存中的产品列表,例如

searchShoppingCart = shoppingCart.ToList().Where(m => productName.Equals(_ProductRepository.GetProductName(m.Id)))

当然,这很糟糕,因为它违背了整个目的!

更好的解决方案是在购物车对象中公开产品可导航属性,并使用相同的属性,例如

searchShoppingCart = shoppingCart.Where(m => productName.Equals(m.Product.Name))