考虑遵循LINQ-to-NHibernate查询:
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查询中?
答案 0 :(得分:3)
因为LINQ提供程序无法将方法m1转换为兼容的SQL语句。
通过调用ToList<SomeEntity>()
,您正在将整个内容读入内存,然后使用LINQ to Objects进行过滤(并且由于在这种情况下查询未转换为SQL,因此运行查询没有问题)。
不幸的是,没有简单的方法让您获得第一个查询。如果您确实需要使用m1
来过滤结果,则必须首先将内容读入内存。
这不仅仅是一个LINQ to nHibernate限制。在LINQ提供程序使用表达式树将您的代码转换为另一种语言的任何情况下都会发生这种情况(在这种情况下,它试图将您的C#代码转换为SQL语句,这与LINQ to SQL和Entity Framework相同)。
答案 1 :(得分:1)
据推测,方法m1
没有对SQL的翻译(至少,NHibernate LINQ提供程序无法弄清楚如何)。当你没有ToList
时,NHibernate试图弄清楚如何将m1
转换为SQL。当你执行ToList
时,NHibernate不再扮演角色了,它的LINQ-to-Objects可以处理查询。这特定于启用LINQ的ORM; LINQ-to-SQL和EF将遭遇类似的命运。
答案 2 :(得分:1)
我想说你的原始q2查询被翻译成表达式树,然后当NHibernate试图解析它时,它发现该方法不是其实现的一部分。首先使用ToList()将查询转换为集合使用List的LINQ功能,该功能可以支持m1方法。
答案 3 :(得分:0)
我不知道NHibernate,但这会有用吗?
var q2 = q1.where (x => m1(x.prop2) == "def");