これは nHibernate ライブラリの問題ではなく、.NET ジェネリックと Linq 式の問題です。
NHibernate はエンティティ タイプを推測できる可能性がありますが、最初にコードをコンパイルする必要があります。:-)
QueryOver 関数のシグネチャは次のとおりです。
IQueryOver<T, T> QueryOver<T>(string entityName, Expression<Func<T>> alias) where T : class;
Func<T>
a は aと同じ型ではないことに注意してくださいSystem.Linq.Expressions.Expression<T>
。
あなたの例では、Func<T>
a を別の変数として宣言したと仮定していますが、コンパイラはそれを何にキャストするかを判断できません。
呼び出しのいくつかのバリエーションを次に示します。
// 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);
コンパイラにインライン ラムダを式に変換させることができます。これも機能し、コンパイラはすべての型引数を推測します。
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);
ただし、読みやすさのために、汎用パラメーターをそのままにしておくことを好みます。