动态构建 Linq 查询

3
我正在编写一个实现关键词搜索的 LINQ 查询。换句话说,这个查询会返回那些包含关键字的TitleDescriptionId的行。
请参考以下内容:
    public static IQueryable<EmployeeObject> QueryableSQL()
    {
        IQueryable<EmployeeObject> queryable = EmployeeRepository.GetAllEmployee(); 
    }

    public static IList<EmployeeObject> QLike(string txt)
    {
       IList<employeeObject> _emps = QueryableSQL().Where(x => x.Title == txt).ToList();
       return _emps;
    }

到目前为止,一切都很顺利。但这只处理了您想在我的情况下匹配 Title 的情况。
相反地,假设我想基于“DescriptionId进行搜索,我需要为Description创建一个新方法吗?还是有一种方法可以创建Tree expression`?

1
不要传入一个字符串文本,而是可以传入一个 Func<T, bool> 并在 .Where() 中使用它。 - gleng
你能给我展示一个例子吗? - Nick Kahn
1
这将适用于您在“EmployeeObject”中引入的任何新字段。 - gleng
3个回答

3
public static IQueryable<EmployeeObject> QueryableSQL()
{
    IQueryable<MediaObject> queryable = EmployeeRepository.GetAllEmployee(); 
}

public static IList<EmployeeObject> QLike(Expression<Func<EmployeeObject, bool>> func)
{
   return QueryableSQL().Where(func).ToList();
}

您可以像这样调用它:
QLike(t => t.Title == "MyText");

3
理想情况下,您应该接受一个 Expression<Func<EmployeeObject, bool>> 而不是一个 Func<EmployeeObject, bool>。这将使LINQ提供程序分析谓词并将其包含为原始SQL查询的一部分。如果未过滤的结果集很大,则这可能会产生巨大的差异。这可能是在将一百万条记录读入内存或只读取一条记录之间的区别。 - Mike Strobel
2
非常好,非常整洁,正是我想要的。 - Nick Kahn
@gleng:bool 对于 Expression<Func<T, bool>> 是什么意思? - Nick Kahn

2

看起来您想要比较的属性是动态的,您可以使用反射来实现:

public static IList<EmployeeObject> QLike(string propName, string txt)
{
   PropertyInfo filterProp = typeof(EmployeeObject).GetProperty(propName);
   IList<employeeObject> _emps = QueryableSQL().Where(x => filterProp.GetValue(x, null).ToString() == txt).ToList();
   return _emps;
}

然而,这种方法的缺点是您将最终加载数据库中的所有对象,然后在代码中进行筛选。
如果按照@gleng所展示的方法执行,则Ling to SQL提供程序将能够在生成的SQL语句中进行筛选。在这种情况下,您需要预先编写谓词,并根据要调用的属性调用适当的谓词。

2

你看过Dynamic Linq吗?当然,如果这段文本是用户提供的而不是编译的话。


在发布问题之前,我已经看到过这个了,但我不确定它如何适用于我的情况。 - Nick Kahn

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