2010-10-12 80 views
1

考虑以下LINQ到NHibernate的查询:LINQ查询不无.ToList工作()

var q1 = from se in query.ToList<SomeEntity>() 
    where 
    prop1 == "abc" 
    select se; 

var q2 = from se in q1 
    where 
    m1(se.prop2) == "def" 
    select se; 

q2不会与错误作:“方法M1,未实现”。但与下面的查询代替q2,一切正常的话:

var q2 = from se in q1.ToList<SomeEntity>() 
    where 
    m1(se.prop2) == "def" 
    select se; 

为什么出现这种情况?我怎样才能得到第一个查询工作呢?这是LINQ-to-NHibernate发生的事情,还是发生在所有LINQ查询中?

回答

3

因为LINQ提供者无法将方法m1转换为兼容的SQL语句。通过调用ToList<SomeEntity>(),您正在将整个事物读入内存,然后使用LINQ to Objects进行过滤(并且由于在这种情况下查询不会转换为SQL,因此运行查询没有任何问题)。

不幸的是,有没有简单的方法让你的第一个查询工作。如果您确实需要使用m1来筛选结果,则必须先将内容读入内存。

这不仅仅是一个LINQ to nHibernate限制。 LINQ提供者使用表达式树将代码转换为另一种语言(在这种情况下,它试图将C#代码转换为与LINQ to SQL和实体框架相同的SQL语句)。

+3

这是正确的。然而,NHibernate 3 **不允许你扩展LINQ提供者以支持任何方法调用(当然,你必须知道如何从中创建一个HQL树)。见http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html – 2010-10-12 20:17:55

+0

@Diego Mijelshon:在NHibernate的3惊人的特点,非常感谢通知。 – 2010-10-13 06:14:22

1

推测方法m1没有翻译成SQL(至少,NHibernate的LINQ提供者不知道如何)。当你没有ToList时,NHibernate试图找出如何将m1转换为SQL。当你做ToList时,NHibernate不再扮演一个角色,它的LINQ到对象可以处理查询。这对于启用LINQ的ORM是特定的; LINQ到SQL和EF将遭受类似的命运。

1

我要说的是,你原来Q2查询被翻译成一个表达式树,然后当NHibernate的尝试来分析它,它发现该方法不是其实施的一部分。首先使用ToList()将查询转换为集合使用List可以支持m1方法的LINQ功能。

0

我不知道NHibernate,但会工作吗?

var q2 = q1.where (x => m1(x.prop2) == "def");