1

In NHibernate, the following works perfectly fine:

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

But this:

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

for some reason, does not. From the documentation, both methods take in the name of the entity as a string as the first parameter, but QueryOver complains with the following error message:

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.

I'm fairly sure that this is being caused by the first parameter to QueryOver (the entityName parameter), and not the func parameter.

Why is it that ISession.Get can infer the entity type from the given entity name but ISession.QueryOver cannot?

4

1 回答 1

1

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

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


QueryOver 函数的签名如下:

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

请注意, aFunc<T>与 a 的类型不同System.Linq.Expressions.Expression<T>

在您的示例中,我假设您已将 a 声明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);

但是,我更喜欢保留通用参数,只是为了便于阅读。

于 2013-07-29T03:47:21.797 回答