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

时间:2013-07-29 00:56:43

标签: c# nhibernate types fluent-nhibernate repository-pattern

在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不能?

1 个答案:

答案 0 :(得分:1)

这不是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>适合通用表达式。因此错误&#34;类型参数不能通过用法来推断......&#34;

Func<Company> func = () => companyAlias;

var q3 = this.Session.QueryOver("Company", func);

我们通过明确说明类型来帮助编译器。下面的代码仍然会失败,但我们会得到更好的错误。 &#34;对...的最佳重载匹配有一些无效的参数&#34;

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

如果可能,最好将类型作为通用表达式而不是名称。这样,如果您重命名该类型但忘记更改函数中的字符串,则可以避免潜在的错误。

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

在这种情况下,您甚至不必将通用参数放入。

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

但是,为了便于阅读,我更喜欢保留泛型参数。