linq 将表达式添加到where子句

sg3maiej  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(157)

假设我有这个方法来搜索我的数据库中符合某个关键字的产品:

public List<Product> GetByKeyword(string keyword)
{
    using(var db = new DataEntities())
    {
        var query = db.Products.Where(x => x.Description.Contains(keyword);
        return query.ToList();
    }
}

字符串
这很好,但在我的项目的其他地方,我想只获得活动产品,仍然是通过关键字。我想做的事情如下:

...
var result = ProductStore.GetByKeyword("Apple", x => x.isActive == 1);


因此,我创建了这个方法:

public List<Product> GetByKeyword(string keyword, Func<Product, bool> predicate = null)
{
    using(var db = new DataEntities())
    {
        var query = db.Products.Where(x => x.Description.Contains(keyword);
        if(predicate != null)
            query = query.Where(x => predicate(x));

        return query.ToList();
    }
}


虽然这可以很好地编译,但ToList()调用会生成一个NotSupportedException,因为LINQ不支持Rankke方法。
当然,我可以用另一种方法,即 GetActiveByKeyword(string keyword),但这样我就必须为每一种可能的变化做一个,包括我没有想到的那些。
我怎么才能让这个工作?谢谢!

fxnxkyjh

fxnxkyjh1#

不就是这样吗:

if(predicate != null)
            query = query.Where(predicate);

字符串

neskvpey

neskvpey2#

就像AD.Net说的,它之所以能用Expression,是因为如果你说编译器知道它是一个lambda表达式,

70gysomp

70gysomp3#

假设目的是让您选择的ORM建立查询,并且当您呼叫ToList()函数来撷取记录(具体化记录)时,则使用Expressions<Func<Product,bool>>会给予最佳效能,因为它会形成查询,并让您继续建立其他运算式。相反地,Func<Product,bool>会在将记录撷取至内存之后使用。
你可以这样实现它。

public List<Product> GetByKeyword(string keyword, params Expression<Func<Product, bool>>[] predicate)
        {
            using(var db = new DataEntities())
            {
                var query = db.Products.Where(x => x.Description.Contains(keyword));

                foreach (var func in predicate)
                {
                    query = query.Where(func);
                }

                return query.ToList();
            }
        }

字符串
然后,您可以像这样使用它:

List<Product> result = GetByKeyword("Apple", x => x.isActive == 1, x => x.Description.Contains("Apple"));


如果有用的话告诉我。
最好的祝愿。

相关问题