2011-11-22 50 views
2

考虑下表:(流利)NHibernate的请在

tool 
*toolid 
*n other fields 

process 
*processid 
*n other fields 

toolprocess 
*toolprocessid 
*toolid 
*processid 
*n other fields 

当试图选择所有工具,适用于特定的过程中,我得到了几千选择上toolprocess在我的LINQ的看起来是这样的:

from tool in tools 
where toolprocesses.Any(t=>t.Tool.Id==tool.Id) 
select tool 

其中toolprocesses包含toolprocesses具有相同的ProcessID列表

在SQL我只想写

SELECT * FROM TOOL WHERE toolid IN 
    (SELECT TOOLID FROM TOOLPROCESS WHERE processid = 'someid'); 

它几乎不需要花时间和预期

工作

我怎样才能NHibernate的创建此查询(或类似的东西)?

+0

你会使用QueryOver解决Exists问题吗? – Phill

回答

1

尝试

from t in Session.Query<Tool>() 
join tp in Session.Query<Toolprocess>() on t equals tp.Tool 
where tp.Process.Id == 'someid' 
select t; 

我假设你正在使用NH 3.x的这应该比Select ... Where ...在查询中更快。

+0

感谢您的回复,此结果首先在哪里进行模糊调用。当我将它转换为此方法链时_session.Query ().Where(t => toolProcesses.Contains(t))我得到一个错误“类型不能从使用推断”在包含,因为它期望一个ToolProcess而不是一个工具 –

+0

好的,我对该列表做了误读。请参阅我的编辑。 –

+0

谢谢,这个窍门 –

3

我不知道你是否可以在Query中做到这一点,但你可以在QueryOver/Criteria中做到这一点。

在QueryOver它会是什么样子:

var subQuery = QueryOver.Of<Toolprocess>() 
         .Where(x => x.Process.Id == id) 
         .Select(x => x.Tool.Id); 

var result = session.QueryOver<Tool>() 
        .WithSubquery.WhereProperty(x => x.Id).In(subQuery) 
        .List(); 

http://www.philliphaydon.com/2010/09/28/queryover-with-nhibernate-3-lovin-it/

或者,如果你想要做的存在,而不是在,我在这里的博客上讲述它:

http://www.philliphaydon.com/2011/01/19/revisiting-exists-in-nhibernate-3-0-and-queryover/

+0

谢谢,当使用这个我得到一个不能解决WithSubQuery的符号错误。我是否需要引用一些我没有通过使用NuGet安装NHibernate 3.1.4? –

+0

@亚历山大 - 对不起,它是WithSubquery,没有资本Q. – Phill

+0

是的,这也可以。我更喜欢。存在,因为它更高效。关于阅读,不使用Exists或In总是更好。至少在你使用SQL Server的时候。 –