简体   繁体   English

NHibernate ISession.QueryOver()不能推断类型,但是ISession.Get()可以。为什么?

[英]NHibernate ISession.QueryOver() cannot infer type but ISession.Get() can.. Why is this?

In NHibernate, the following works perfectly fine: 在NHibernate中,以下工作完全正常:

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: 从文档中,这两种方法都将实体名称作为字符串作为第一个参数,但是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.

I'm fairly sure that this is being caused by the first parameter to QueryOver (the entityName parameter), and not the func parameter. 我相当确定这是由QueryOver的第一个参数(entityName参数)引起的,而不是func参数引起的。

Why is it that ISession.Get can infer the entity type from the given entity name but ISession.QueryOver cannot? 为什么ISession.Get可以从给定的实体名称推断出实体类型,但是ISession.QueryOver却不能呢?

This is not an issue with the nHibernate library, it's an issue with .NET generics and Linq expressions. 这不是nHibernate库的问题,而是.NET泛型和Linq表达式的问题。

NHibernate might be capable of inferring the entity type, but you have to get the code to compile first. NHibernate可能能够推断实体类型,但是您必须先获取代码才能进行编译。 :-) :-)


The signature for the QueryOver function is as follows: QueryOver函数的签名如下:

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

Note that a Func<T> is not the same type as a System.Linq.Expressions.Expression<T> . 请注意, Func<T>System.Linq.Expressions.Expression<T>

In your example, I assume you have declared a Func<T> as a separate variable, and the compiler is unable to figure out what to cast it too. 在您的示例中,我假设您已将Func<T>声明为单独的变量,并且编译器也无法弄清楚该如何进行强制转换。

Here are some variations of the call: 这是电话的一些变化:

// 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);

We can let the compiler turn an in-line lambda into an expression. 我们可以让编译器将内联lambda转换为表达式。 This works too, and the compiler infers all of the type arguments. 这也可行,并且编译器会推断所有类型参数。

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

It will fail if we use a plain function object instead of an expression. 如果我们使用普通函数对象而不是表达式,它将失败。 Here, the compiler can't figure out how to make the Func<Company> fit into the generic expression. 在这里,编译器无法弄清楚如何使Func<Company>适应通用表达式。 Hence the error "The type arguments cannot be inferred by the usage..." 因此,错误“类型参数不能通过用法推断出来……”

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

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

We help the compiler by explicitly stating the type. 我们通过明确说明类型来帮助编译器。 The code below will still fail, but we get a better error. 下面的代码仍然会失败,但是会得到更好的错误。 "The best overload match for ... has some invalid arguments" “ ...的最佳重载匹配具有一些无效的参数”

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

If possible, it's best to give it the type as a generic expression rather than the name. 如果可能的话,最好将其类型指定为通用表达式而不是名称。 That way you avoid potential errors if you ever rename the type but forget to change the string in the function. 这样,就可以避免潜在的错误(如果您曾经重命名类型但忘记了在函数中更改字符串)。

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

You don't even have to put the generic parameter in in this case. 在这种情况下,您甚至不必放入通用参数。

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

However, I prefer to keep the generic parameter in, just for the sake of readability. 但是,出于可读性考虑,我更喜欢保留通用参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NHibernate的ISession.QueryOver是否会触发任何事件? - Does NHibernate's ISession.QueryOver fire any events? 如何在 ISession.QueryOver 中添加“或”语句? - How to add "or" statement in ISession.QueryOver? 带有复合键的实体上的NHibernate ISession.Get()引发InvalidCastException - NHibernate ISession.Get() on entity with composite key throws InvalidCastException 使用NHibernate的ISession.Get &lt;&gt;()w /复合键 - Using NHibernate's ISession.Get<>() w/ a composite key 调用NHibernate ISession.get <T> (对象id)两次具有相同的id返回两个不同的实例 - Calling NHibernate ISession.get<T>(object id) twice with the same id returns two different instances MEF + nHibernate + Fluent NHibernate-无法转换(ContractName =“ NHibernate.ISession”)&#39;来键入&#39;NHibernate.ISession&#39; - MEF + nHibernate + Fluent NHibernate - Cannot cast (ContractName=“NHibernate.ISession”)' to type 'NHibernate.ISession' Moq NHiberNate ISession.Get不调用模拟会话对象 - Moq NHiberNate ISession.Get doesn't call mock session object NHibernate ISession.Delete - NHibernate ISession.Delete 使用Moq模拟NHibernate ISession - Mocking an NHibernate ISession with Moq 无法使用 [] 将索引应用于“ISession”类型的表达式 - Cannot apply indexing with [] to an expression of type "ISession"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM