linq - 是否有必要在 LINQ 查询中不使用方法?

标签 linq linq-to-nhibernate

在以下代码中,当我直接将“dl.DamageCount > 5”放入查询中或将“dl.DamageCount > 5”移动到方法或函数然后仅从查询中调用它时,有什么区别吗?

似乎当我将其移动到方法中时,查询无法正常工作。事实上,无论条件评估如何,函数/方法似乎总是返回 true。我正在使用 Linq-to-NHibernate。

 var q = from dl in session.Linq<DamageList>()
            where
            dl.DamageCount > 5

最佳答案

您能做的最好的事情就是捕获 Expression<> 中的谓词。 。方法已编译为 IL,因此 Linq 提供程序无法将其拆开。

Expression<Func<DamageList, bool>> predicate = item => item.DamageCount > 5;

然后您可以将该谓词直接传递给 Where :

var q = session.Linq<DamageList>().Where(predicate);

如果您想动态组合两个这样的表达式,您可以将这两个表达式的代码写入一个表达式中,或者在单独的表达式中捕获这两个表达式。这变得很复杂,因为您需要每个都引用 item这确实是一个不同的问题,已经被问过:How do I dynamically create an Expression<Func<MyClass, bool>> predicate?

您可以使用 && 运算符编写复合谓词,并仍然在表达式中捕获它:

Expression<Func<DamageList, bool>> predicate = 
    dl => dl.DamageCount > 5 && dl.Name.Contains(criteria);

您询问有关在这样的表达式中调用方法的问题 - 好吧,该示例确实调用了一个方法!

它构建了一棵树 Expression各种类型的节点。某处包含一个方法调用节点,它表示调用 Contains方法string (假设 Namestring )。这是嵌入在表达式中的方法调用指令的示例。为了使其工作,Linq 提供程序必须知道该方法的作用,以便它可以将其转换为等效的 SQL(就像典型的 ORM 系统的情况一样)。

因此,您可以在表达式中嵌入某些标准方法调用 - 它需要 Linq 提供程序了解它们。 string的方法定义明确,但并非每个提供商都一定能够处理所有这些问题。

Linq 提供商允许您添加自己的扩展来处理额外的方法并非不可能,但我不知道有任何支持该功能的扩展(显然,如果系统是开源的,您可以添加自己的扩展)自己的)。

总而言之,Linq 提供程序需要一棵表达式节点树,它可以对其进行分析,将其转换为某种其他语言(例如 SQL),以便在另一个上下文(例如远程数据库内)中执行。如果您编写普通方法,C#编译器会将它们编译为低级可执行IL,而不是表达式节点。所以这就像一个死胡同:没有内置工具可以将 IL 转回表达节点。

关于linq - 是否有必要在 LINQ 查询中不使用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2305691/

相关文章:

c# - 强制转换并转换为基类对象的集合不起作用

c# - 如何在 C# 中为 int 列表构建直方图

nhibernate - 是否有用于无状态 session 的 Linq to Nhibernate?

nhibernate - LINQ to NHibernate 存在于何处

linq - 使用 LINQ 的分层数据总和?

每个项目的 LINQ to SQL : Multiple/Single . dbml?

c# - 在 LINQ-to-NHibernate 或 LINQ 中比较枚举时有什么考虑吗?

LINQ to NHibernate - 将 guid 与字符串进行比较

c# - Mongodb C# 查询嵌套文档

c# - Linq 到 NHibernate : Sequence Contains no Elements