NHibernate ISession.QueryOver()无法推断类型,但ISession.Get()可以.为什么会

本文关键字:ISession Get 可以 为什么 QueryOver NHibernate 类型 | 更新日期: 2023-09-27 18:25:20

在NHibernate中,以下操作非常好:

Session.Get(repoType.ToString(), id))

但是这个:

Session.QueryOver(repoType.ToString(), func)

出于某种原因,没有。从文档中,两种方法都将实体的名称作为字符串作为第一个参数,但QueryOver会发出以下错误消息:

The type arguments for method 'NHibernate.ISession.QueryOver<T>(string, System.Linq.Expressions.Expression<System.Func<T>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

我确信这是由QueryOver的第一个参数(entityName参数)引起的,而不是func参数。

为什么ISession.Get可以从给定的实体名称推断实体类型,而ISession.QueryOver不能?

NHibernate ISession.QueryOver()无法推断类型,但ISession.Get()可以.为什么会

这不是nHibernate库的问题,而是.NET泛型和Linq表达式的问题。

NHibernate可能能够推断实体类型,但您必须首先获得要编译的代码。:-)


QueryOver函数的签名如下:

IQueryOver<T, T> QueryOver<T>(string entityName, Expression<Func<T>> alias) where T : class;

注意,Func<T>System.Linq.Expressions.Expression<T>的类型不同。

在您的示例中,我假设您已经将Func<T>声明为一个单独的变量,而编译器也无法确定要强制转换它的内容。

以下是呼叫的一些变体:

// Defining the second parameter explicitly as an expression.
// This works
Company companyAlias = null;
System.Linq.Expressions.Expression < Func < Company >> expression = () => companyAlias;
var q1 = this.Session.QueryOver("Company", expression);

我们可以让编译器将内联lambda转换为表达式。这也起作用,编译器推断出所有的类型参数。

var q2 = this.Session.QueryOver("Company", () => companyAlias);

如果我们使用纯函数对象而不是表达式,它将失败。在这里,编译器无法弄清楚如何使Func<Company>适合通用表达式。因此,错误"类型参数不能通过用法推断…"

Func<Company> func = () => companyAlias;
var q3 = this.Session.QueryOver("Company", func);

我们通过显式声明类型来帮助编译器。下面的代码仍然会失败,但我们得到了一个更好的错误。"的最佳重载匹配…有一些无效参数"

var q4 = this.Session.QueryOver<Company>("Company", func);

如果可能的话,最好将类型作为泛型表达式,而不是名称。这样可以避免在重命名类型但忘记更改函数中的字符串时可能出现的错误。

var q = session.QueryOver<Company>(() => companyAlias);

在这种情况下,您甚至不必放入泛型参数。

var q = session.QueryOver(() => companyAlias);

但是,为了可读性,我更喜欢保留泛型参数。