2013-04-08 30 views
7

我看various questions在SO和other sites,這似乎是執行在LINQ一個JOIN正確的語法,但它只是不工作:這個LINQ JOIN是否有某種語法錯誤?

var stages = (from stage in entityManager.TPM_TASKSTAGE select stage); 
var results = (from task in pv.TPM_TASK 
       join st in stages on st.STAGEID equals task.STAGEID 
       where task.TASKTYPE == "Solution" 
       select new SolutionTask()); 

忽略,現在,事實我實際上並沒有選擇任何有趣的事情,但我想訪問TPM_TASK的每行st.NAME財產。這兩張表由STAGEID連接。我得到的編譯器錯誤:

The name 'st' is not in scope on the left side of 'equals'. Consider swapping the expressions on either side of 'equals'.

在LINQ加入表達,既sttask有紅色squigglies。請告訴我,我正在做一些愚蠢的事情。

+1

您是否嘗試遵循錯誤消息中的確切說明? (「考慮交換'等於'兩邊的表達式」) – 2013-04-08 21:41:35

+0

@JonSkeet - 這實際上是我嘗試的第一件事,但是我的表達式是'task.STAGEID == st.STAGEID'。這產生了一個類似的編譯器錯誤(建議我交換表達式)。所以我做了,並且也轉向「平等」,認爲這可能會有所作爲。我沒有嘗試'task.STAGEID等於st.STAGEID'這是有效的組合!嘆。 – 2013-04-08 21:45:38

+0

當你有'task.STAGEID == st.STAGEID'時,你不會得到相同的錯誤信息,因爲你的連接在那個時候*完全*無效。 – 2013-04-08 21:46:32

回答

11

來自外部序列的關鍵選擇器應該先進行。外殼順序是pv.TPM_TASK。因此,您應該加入task.STAGEID equals st.STAGEID

var stages = (from stage in entityManager.TPM_TASKSTAGE select stage); 
var results = (from task in pv.TPM_TASK 
       join st in stages on task.STAGEID equals st.STAGEID // here 
       where task.TASKTYPE == "Solution" 
       select new SolutionTask()); 
+1

挑剔的編譯器。非常感謝! – 2013-04-08 21:41:32

+0

@MikeChristensen:這實在不是挑剔的問題。 'equals'的兩邊有着完全不同的範圍:左邊沒有'st'的知識,右邊沒有'task'的知識。對於這類事情,考慮查詢表達式語法的真正意義是很有用的。有關更多詳細信息,請參閱http://msmvps.com/blogs/jon_skeet/archive/2011/01/28/reimplementing-linq-to-objects-part-41-how-query-expressions-work.aspx。 – 2013-04-08 21:48:16

+0

@JonSkeet - 感謝您的信息!我有點兒是LINQ新手,當涉及到更復雜的連接時,我很容易被拋棄。我想他們的工作類似於SQL JOIN,其中操作數的順序並不重要。 – 2013-04-08 21:53:05